zookeeper实现动态上下线

 分析:

对于zookeeper集群而言服务器端和客户端都是它的客户端

只是服务器端对于此案列而言充当了写的功能,客户端充当了读的功能

步骤:

服务器端:

1连接到zookeeper集群

2实现每台服务器在/servers/下创建一个临时节点(节点名称和内容都是该服务器的主机名)

客户端:

1连接到zookeeper集群

2监视/servers/下的节点变化,并打印/servers/下节点的内容,就知道哪些服务器还在线上(因为创建的是临时节点,当服务器下线后/servers/下相应的节点会删除)

自己对于代码中的一些思考:

1在zookeeper里面的监视器添加后只能执行一次,所以怎么能永久监听呢?

在process里面监听一次后再次设置一次监听就好(也就是getServerList()函数中的zk.getChildren(parentNode, true)),以此循环下去,就能实现一直监听

2为什么客户端和服务器端都要Thread.sleep(Long.MAX_VALUE)?

因为不设置的话主程序里面的代码一下就跑完了,实现不了一直监听的作用,Thread.sleep(Long.MAX_VALUE)就让程序进行睡眠,Thread.sleep(Long.MAX_VALUE)之前的代码中监听器是可以继续工作的

servers代码:

import org.apache.zookeeper.*;

import java.io.IOException;

public class Servers {
    private static String connectString="hadoop200:2181,hadoop201:2181,hadoop202:2181";
    private static int sessionTimeout = 2000;
    private ZooKeeper zk = null;
    private String parentNode = "/servers";

    // 创建到 zk 的客户端连接
    public void getConnect() throws IOException {
        zk = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
            public void process(WatchedEvent watchedEvent) {

            }
        });
    }

    // 注册服务器
    public void registServer(String hostname) throws Exception {
        String create = zk.create("/servers/" + hostname, hostname.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
        System.out.println(hostname + " is online " + create);
    }

    // 业务功能
    public void business(String hostname) throws Exception {
        System.out.println(hostname + " is working ...");
        Thread.sleep(Long.MAX_VALUE);
    }

    public static void main(String[] args) throws Exception {
        // 1 获取 zk 连接
        Servers server = new Servers();
        server.getConnect();
        // 2 利用 zk 连接注册服务器信息
        server.registServer(args[0]);
        // 3 启动业务功能
        server.business(args[0]);
    }

}

Client代码:

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 Client {
    private static String connectString="hadoop200:2181,hadoop201:2181,hadoop202:2181";
    private static int sessionTimeout = 2000;
    private ZooKeeper zk = null;
    private String parentNode = "/servers";
    // 创建到 zk 的客户端连接
    public void getConnect() throws IOException {
        zk = new ZooKeeper(connectString, sessionTimeout, new Watcher() {

            public void process(WatchedEvent event) {
                // 再次启动监听
                try {
                    getServerList();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
    // 获取服务器列表信息
    public void getServerList() throws Exception {
        // 1 获取服务器 子节点信息,并且对父节点进行监听
        List<String> children = zk.getChildren(parentNode, true);
        // 2 存储服务器信息列表
        ArrayList<String> servers = new ArrayList<String>();
        // 3 遍历所有节点,获取节点中的主机名称信息
        for (String child : children) {
            byte[] data = zk.getData(parentNode + "/" + child,false, null);
            servers.add(new String(data));
        }
        // 4 打印服务器列表信息
        System.out.println(servers);
    }
    // 业务功能
    public void business() throws Exception{
        System.out.println("client is working ...");
        Thread.sleep(Long.MAX_VALUE);
    }
    public static void main(String[] args) throws Exception {
        // 1 获取 zk 连接
        Client client = new Client();
        client.getConnect();
        // 2 获取 servers 的子节点信息,从中获取服务器信息列表
        client.getServerList();
        // 3 业务进程启动
        client.business();
    }

}

猜你喜欢

转载自blog.csdn.net/qq_52135683/article/details/126781636