• Zookeeper (四) --------- 服务器动态上下线监听案例



    一、需求及需求分析

    需求

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

    需求分析

    在这里插入图片描述

    二、具体实现

    A、先在集群上创建 /servers 节点

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

    B、在 Idea 中创建包名

    com.fancy.zkcase1

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

    package com.fancy.zkcase1;
    import java.io.IOException;
    import org.apache.zookeeper.CreateMode;
    import org.apache.zookeeper.WatchedEvent;
    import org.apache.zookeeper.Watcher;
    import org.apache.zookeeper.ZooKeeper;
    import org.apache.zookeeper.ZooDefs.Ids;
    public class DistributeServer {
    	private static String connectString = "hadoop102:2181,hadoop103:2181,hadoop104: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() {
    			@Override
    			public void process(WatchedEvent event) {
    			}
    		});
    	}
    	
    	// 注册服务器
    	public void registServer(String hostname) throws Exception{
    		String create = zk.create(parentNode + "/server",hostname.getBytes(), 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 连接
    		DistributeServer server = new DistributeServer();
    		server.getConnect();
    		// 2 利用 zk 连接注册服务器信息
    		server.registServer(args[0]);
    		// 3 启动业务功能
    		server.business(args[0]);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    D、客户端代码

    package com.atguigu.zkcase1;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    import org.apache.zookeeper.WatchedEvent;
    import org.apache.zookeeper.Watcher;
    import org.apache.zookeeper.ZooKeeper;
    public class DistributeClient {
    	
    	private static String connectString = "hadoop102:2181,hadoop103:2181,hadoop104: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() {
    			@Override
    			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<>();
    		// 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 连接
    		DistributeClient client = new DistributeClient();
    		client.getConnect();
    		// 2 获取 servers 的子节点信息,从中获取服务器信息列表
    		client.getServerList();
    		// 3 业务进程启动
    		client.business();
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    三、测试

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

    A、启动 DistributeClient 客户端
    B、在 hadoop102 上 zk 的客户端 /servers 目录上创建临时带序号节点

    [zk: localhost:2181(CONNECTED) 1] create -e -s
    /servers/hadoop102 "hadoop102"
    [zk: localhost:2181(CONNECTED) 2] create -e -s
    /servers/hadoop103 "hadoop103"
    
    • 1
    • 2
    • 3
    • 4

    C、观察 Idea 控制台变化

    [hadoop102, hadoop103]
    
    • 1

    D、执行删除操作

    [zk: localhost:2181(CONNECTED) 8] delete
    /servers/hadoop1020000000000
    
    • 1
    • 2

    E、观察 Idea 控制台变化

    [hadoop103]
    
    • 1

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

    A、启动 DistributeClient 客户端(如果已经启动过,不需要重启)

    B、启动 DistributeServer 服务

    ①点击 Edit Configurations…

    在这里插入图片描述
    在这里插入图片描述
    ③ 回 到 DistributeServer 的 main 方 法 , 右 键 , 在 弹 出 的 窗 口 中 点 击 Run DistributeServer.main()

    在这里插入图片描述

    ④ 观察 DistributeServer 控制台,提示 hadoop102 is working

    ⑤ 观察 DistributeClient 控制台,提示 hadoop102 已经上线

  • 相关阅读:
    向世界展示“中国品牌”实力,中海达参展INTERGEO
    2023App测试必掌握的核心测试:UI、功能测试
    WMS仓库管理系统库位分配规划
    java Spring Boot验证码美化,白色背景 随机四个数 每个字随机颜色
    MindSpore:对image作normalize的目的是什么?
    Java ~ Executor ~ LinkedBlockingQueue【源码】
    vscode按ctrl+鼠标左键没反应
    【编程题】【Scratch四级】2022.09 绘制图形
    java常用部署脚本
    模拟BIO实战--实现一个线程对应一个客户端
  • 原文地址:https://blog.csdn.net/m0_51111980/article/details/125998277