Zookeeper3.5.7版本——服务器动态上下线监听案例

一、案例需求

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

二、案例需求分析

  • 服务端启动时去注册信息(创建都是临时节点)。

    在这里插入图片描述

  • 获取到当前在线服务器列表,并且注册监听。
    在这里插入图片描述

  • 服务器节点下线。
    在这里插入图片描述

  • 服务器节点上下线事件通知。
    在这里插入图片描述

  • 重新再去获取服务器列表,并注册监听。
    在这里插入图片描述

三、案例具体代码实现

3.1、在集群上创建 servers 节点

  • 创建 servers 节点

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

    在这里插入图片描述

3.2、服务器端向 Zookeeper 注册代码

  • 服务注册器

    package com.xz.case1;
    
    import org.apache.zookeeper.*;
    import java.io.IOException;
    
    public class DistributeServer {
          
          
    
        private String connectString = "192.168.136.27:2181,192.168.136.28:2181,192.168.136.29:2181";
        private int sessionTimeout = 200000;
        private ZooKeeper zk;
    
        public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
          
          
            DistributeServer server = new DistributeServer();
            // 1 获取zk连接
            server.getConnect();
    
            // 2 注册服务器到zk集群
            server.regist("192.168.136.27");
    
            // 3 启动业务逻辑
            server.business();
        }
        /**
         * 3、启动业务逻辑
         * */
        private void business() throws InterruptedException {
          
          
            Thread.sleep(Long.MAX_VALUE);
        }
        /**
         * 2、注册服务器到zk集群
         * */
        private void regist(String hostname) throws KeeperException, InterruptedException {
          
          
            String create = zk.create("/servers/"+hostname, hostname.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
            System.out.println(hostname +" is online") ;
        }
        /**
         * 1、获取zk连接
         * */
        private void getConnect() throws IOException {
          
          
            zk = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
          
          
                @Override
                public void process(WatchedEvent watchedEvent) {
          
          
    
                }
            });
        }
    }
    

3.3、客户端监听代码

  • 客户端监听代码

    package com.xz.case1;
    
    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 = "192.168.136.27:2181,192.168.136.28:2181,192.168.136.29:2181";
        private int sessionTimeout = 200000;
        private ZooKeeper zk;
    
        public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
          
          
            DistributeClient client = new DistributeClient();
            // 1 获取zk连接
            client.getConnect();
    
            // 2 监听/servers下面子节点的增加和删除
            client.getServerList();
    
            // 3 业务逻辑
            client.business();
        }
    
        private void business() throws InterruptedException {
          
          
            Thread.sleep(Long.MAX_VALUE);
        }
        /**
         * 2 监听/servers下面子节点的增加和删除
         * */
        private void getServerList() throws KeeperException, InterruptedException {
          
          
            //监听路径 servers
            List<String> children = zk.getChildren("/servers", true);
            ArrayList<String> servers = new ArrayList<>();
            //遍历路径 servers下的所有节点
            for (String child : children) {
          
          
                byte[] data = zk.getData("/servers/" + child, false, null);
                servers.add(new String(data));
            }
            // 打印
            System.out.println(servers);
        }
        /**
         * 1、获取zk连接
         * */
        private void getConnect() throws IOException {
          
          
            zk = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
          
          
                @Override
                public void process(WatchedEvent watchedEvent) {
          
          
                    try {
          
          
                        getServerList();
                    } catch (KeeperException e) {
          
          
                        e.printStackTrace();
                    } catch (InterruptedException e) {
          
          
                        e.printStackTrace();
                    }
                }
            });
        }
    }
    

四、测试

4.1、在 Linux 命令行上操作增加减少服务器

  • 启动 DistributeClient 客户端
    在这里插入图片描述

  • 在 192.168.136.27服务器上 zk 的客户端/servers 目录上创建临时带序号节点

    [zk: localhost:2181(CONNECTED) 3] create  -e  -s /servers/192.168.136.28  "28"
    [zk: localhost:2181(CONNECTED) 4] create  -e  -s /servers/192.168.136.29  "29"
    

    在这里插入图片描述

  • 观察 Idea 控制台变化
    在这里插入图片描述

  • 执行删除操作

    [zk: localhost:2181(CONNECTED) 5] delete /servers/192.168.136.280000000000
    

    在这里插入图片描述

  • 观察 Idea 控制台变化
    在这里插入图片描述

4.2、在 Idea 上操作增加减少服务器

  • 启动 DistributeClient 客户端(如果已经启动过,不需要重启)
    在这里插入图片描述
  • 启动 DistributeServer 服务,观察 DistributeServer 控制台,提示 192.168.136.27服务 is working
    在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/li1325169021/article/details/129699436