三, 利用Zookeeper实现 服务器动态上下线

三, 利用Zookeeper实现 服务器动态上下线

3.1 需求

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

3.2 需求分析

请添加图片描述

3.3 具体实现

  1. 先在集群上创建/servers 节点
[zk: localhost:2181(CONNECTED) 0] create /servers "servers"
Created /servers
  1. IDEA中创建包名cn.qsc.zkcase1

  2. 新建java类, DistributeServer.java

如果对于某些方法的实现有疑问, 参见前面文章中zookeeper的API操作-3.3 小节

/**
 * 服务器端的实现功能:
 * 1. 与zk集群进行连接
 * 2. 注册服务器到zk集群(即在zk集群中建立临时的代表服务器在线的节点)
 * 3. 实现服务器的一些运行逻辑(直接让服务器休眠以避免程序过快结束, 以后我们可以在这里面实现一些复杂的业务逻辑)
 */
public class DistributeServer {
    
    

    private static String connectString = "bigdata01:2181,bigdata02:2181,bigdata03:2181";
    private static int sessionTimeout = 2000;
    private ZooKeeper zk;

    public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
    
    
        DistributeServer server = new DistributeServer();

        //1. 获取zk连接
        server.getConnect();

        //2. 注册服务器到集群(在zk集群中创建znode节点, 节点的值就是上线的服务器名称)
        server.register(args[0]);

        //3. 实现服务器的一些运行逻辑
        //休眠, 避免程序立马就结束
        server.business();
    }

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

    private void register(String hostname) throws InterruptedException, KeeperException {
    
    

        //创建临时的带序号的znode节点, 这个节点的数据就是服务器的名称
        zk.create("/servers/"+hostname, hostname.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);

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

    private void getConnect() throws IOException {
    
    
        zk = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
    
    
            @Override
            public void process(WatchedEvent watchedEvent) {
    
    
                //监听器的一些实现逻辑
            }
        });
    }


}
  1. 新建java类, DistributeClient.java
/**
 * 客户端的实现功能:
 * 1. 与zk集群进行连接
 * 2. 监听zk集群 /servers 路径下节点的增加和减少变化(代表着服务器的上线和下线), ls -w /servers
 * 3. 实现客户端的一些运行逻辑(直接让客户端休眠以避免程序过快结束, 以后我们可以在这里面实现一些复杂的业务逻辑)
 */
public class DistributeClient {
    
    

    private static String connectString = "bigdata01:2181,bigdata02:2181,bigdata03:2181";
    private static int sessionTimeout = 2000;

    private ZooKeeper zk;

    public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
    
    
        DistributeClient client = new DistributeClient();

        //1. 与zk集群进行连接
        client.getConnect();

        //2. 建立监听器
        client.getServerList();

        //3. 业务逻辑(休眠)
        client.business();
    }

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

    private void getServerList() throws InterruptedException, KeeperException {
    
    

        List<String> servers = zk.getChildren("/servers", true);

        List<String> serverData = new ArrayList<>();

        for (String server : servers) {
    
    
            //获取路径下的节点数据并存放到集合中去

            //易错点: 拼接子节点!!!!
            byte[] data = zk.getData("/servers/"+server, false, null);

            //data封装为String对象, 然后存放到集合中;
            serverData.add(new String(data));
        }

        //直接输出集合, 显示znode节点内容(上线服务器信息)
        System.out.println(serverData);
    }

    private void getConnect() throws IOException {
    
    

        zk = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
    
    
            @Override
            public void process(WatchedEvent watchedEvent) {
    
    
                try {
    
    
                    getServerList();
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                } catch (KeeperException e) {
    
    
                    e.printStackTrace();
                }
            }
        });
    }
}

3.4 测试

  1. 对客户端实现类, DistributeClient, 单独测试如下

在这里插入图片描述

  1. 开启客户端实现类DistributeClient的同时, 开启服务器端实现类DistributeServer, 并做以下操作:
  • 1.配置
    在这里插入图片描述

    1. 传入参数
      在这里插入图片描述
    1. 启动DistributeServer, 控制台应该有方框中的内容
      在这里插入图片描述
    1. 同时DistributeClient的控制台会同步显示出上面我们加入的参数
      在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/nmsLLCSDN/article/details/119206897