zookeeper实现节点动态上下线感知

zookeeper实现节点动态上下线感知

节点动态上下线感知的实现原理

Zookeeper 是一个分布式协调服务,可以管理(存储、读取)用户程序提交的数据,并为用户程序提供数据节点监听服务。
节点动态上下线感知就是利用Zookeeper的节点监听功能,服务端程序上线时,在zookeeper上创建一个临时有序节点,临时节点具有当session不存在该节点就从Zookeeper上会自动删除的功能。

客户端程序一启动就监听Zookeeper上存放服务器创建临时节点的父节点,当父节点下的子节点有增加或者减少时,客户端程序的监听就会被回调,在回调方法中可以重新获取能提供服务的服务器节点信息。

具体实现

使用idea + maven开发

引入依赖

        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.6</version>
            <!--<type>pom</type>-->
        </dependency>

服务器端代码

package cn.zhou.bigdata.zkdist;

import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class DistributedClient {


    private static String connectionStr = "mini41:2181,mini42:2181,mini43:2181";
    private static int sessionTimeOut = 2000;
    private static ZooKeeper zkClient;
    public static final String PARENT_NODE_NAME = "/servers";

    private static volatile ArrayList<String> servers;

    public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
        // getChildren and register watcher
        getConnection();

        // get Available servers
        getAvailableServers();

        doBusiness();

    }


    public static void getConnection() throws IOException {
        zkClient = new ZooKeeper(connectionStr, sessionTimeOut, new Watcher() {
            public void process(WatchedEvent watchedEvent) {
                try {
                    if (watchedEvent.getType() == Event.EventType.NodeChildrenChanged && PARENT_NODE_NAME.equals(watchedEvent.getPath())) {
                        getAvailableServers();
                    }
                } catch (KeeperException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public static void getAvailableServers() throws KeeperException, InterruptedException {
        ArrayList<String> serverList = new ArrayList<String>();
        List<String> children = zkClient.getChildren(PARENT_NODE_NAME, true);
        for (String child : children) {
            byte[] data = zkClient.getData(PARENT_NODE_NAME + "/" + child, null, null);
            serverList.add(new String(data));
        }
        servers = serverList;
        System.out.println("The list of servers that can provide services is " + servers);
    }

    private static void doBusiness() throws InterruptedException {
        System.out.println("do your business  " + servers);
        Thread.sleep(Integer.MAX_VALUE);
    }
}

客户端代码

package cn.zhou.bigdata.zkdist;

import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class DistributedClient {


    private static String connectionStr = "mini41:2181,mini42:2181,mini43:2181";
    private static int sessionTimeOut = 2000;
    private static ZooKeeper zkClient;
    public static final String PARENT_NODE_NAME = "/servers";

    private static volatile ArrayList<String> servers;

    public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
        // getChildren and register watcher
        getConnection();

        // get Available servers
        getAvailableServers();

        doBusiness();

    }


    public static void getConnection() throws IOException {
        zkClient = new ZooKeeper(connectionStr, sessionTimeOut, new Watcher() {
            public void process(WatchedEvent watchedEvent) {
                try {
                    if (watchedEvent.getType() == Event.EventType.NodeChildrenChanged && PARENT_NODE_NAME.equals(watchedEvent.getPath())) {
                        getAvailableServers();
                    }
                } catch (KeeperException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public static void getAvailableServers() throws KeeperException, InterruptedException {
        ArrayList<String> serverList = new ArrayList<String>();
        List<String> children = zkClient.getChildren(PARENT_NODE_NAME, true);
        for (String child : children) {
            byte[] data = zkClient.getData(PARENT_NODE_NAME + "/" + child, null, null);
            serverList.add(new String(data));
        }
        servers = serverList;
        System.out.println("The list of servers that can provide services is " + servers);
    }

    private static void doBusiness() throws InterruptedException {
        System.out.println("do your business  " + servers);
        Thread.sleep(Integer.MAX_VALUE);
    }
}

运行结果

先启动zookeeper集群,然后分别运行DistributedServer和DistributedClient

启动DistributedServer,启动传入mini1
启动DistributedServer,启动传入mini1
启动DistributedClient
启动DistributedClient

再启动一个DistributedServer,模拟新的服务端程序上线操作,启动传入mini2
在这里插入图片描述
客户端已经获取到服务器
在这里插入图片描述

停掉mini1的服务器端
提供的服务由[mini2,mini1]变成[mini2]

可以提供的服务器列表由[mini2,mini1]变成[mini2],目前只有mini2才能提供服务。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值