Zookeeper监听服务器节点动态上下线案例

时间秒杀一切 提交于 2019-12-02 00:08:21

1.需求

  某分布式系统中,主节点可以有多台,可以动态上下线,任意一台客户端都能实时感知到主节点服务器的上下线。

2.需求分析

 

 

3.具体实现

(0)先在集群上创建/servers节点:

[zk: localhost:2181(CONNECTED) 10] create /servers "servers"
Created /servers

1)服务器端向Zookeeper注册代码:

import org.apache.zookeeper.*;
import org.jetbrains.annotations.NotNull;

import java.io.IOException;

public class DistributeServer {

    public static void main(@NotNull String[] args) throws IOException, KeeperException, InterruptedException {

        DistributeServer server = new DistributeServer();
//  思路:先写大框架!在考虑细节

//        1.连接zookeeper集群
        server.getConnect();

//        2.注册节点
        server.regist(args[0]);

//        3.业务逻辑处理
        server.business();
    }

    private void business() throws InterruptedException {
//        睡眠,保证进程不结束
        Thread.sleep(Long.MAX_VALUE);

    }

    private void regist(String hostname) throws KeeperException, InterruptedException {
//      由于每次注册只调用下面这一个方法,故设置CreateMode时只能设置临时带序号的类型
        zkClient.create("/servers/server",hostname.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);

        System.out.println(hostname + " is online !");
    }

    private String connectString = "hadoop102:2181,hadoop103:2181,hadoop104:2181";
    private int sessionTimeout = 2000;
    private ZooKeeper zkClient;//客户端对象

    private void getConnect() throws IOException {

        zkClient = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
            public void process(WatchedEvent event) {

            }
        });
    }

}

 

 

 

(2)客户端代码

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 DistributeClient  {
    private String connectString = "hadoop102:2181,hadoop103:2181,hadoop104:2181";
    private int sessionTimeout = 2000;
    private ZooKeeper zkClient;//客户端对象

    public static void main(String[] args) throws IOException, KeeperException, InterruptedException {

        DistributeClient client = new DistributeClient();
//        1.获取zookeeper集群连接
        client.getConnect();
        
//        2. 注册监听
        client.getChildren();

//        3.业务逻辑处理
        client.business();
    }

    private void business() throws InterruptedException {
        Thread.sleep(Long.MAX_VALUE);
    }

    private void getChildren() throws KeeperException, InterruptedException {
//              监听/servers  启动监听之后会进入new Watcher()的process方法中
        List<String> children = zkClient.getChildren("/servers", true);

//        存储服务器节点主机的名称,放在集合里
        ArrayList<String> hosts = new ArrayList<String>();;

        for (String child :
                children) {
//                          拼接可得要获得的数据目的地
            byte[] data = zkClient.getData("/servers/" + child, false, null);
            hosts.add(new String(data));
        }

//        将所有在线主机名称打印到控制台
        System.out.println(hosts);
        
    }

    private void getConnect() throws IOException {

        zkClient = new ZooKeeper(connectString, sessionTimeout, new Watcher() {

            public void process(WatchedEvent event) {
                System.out.println("启用的监听!");

//              如果不将下面的代码放在此处,那么监听只会执行一次

                try {
//                    为了动态监听
                    getChildren();
                } catch (KeeperException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }


            }
        });
    }
}

要记得在运行时候main中args[ ]要事先配置哦!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!