• 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代码:

    1. import org.apache.zookeeper.*;
    2. import java.io.IOException;
    3. public class Servers {
    4. private static String connectString="hadoop200:2181,hadoop201:2181,hadoop202:2181";
    5. private static int sessionTimeout = 2000;
    6. private ZooKeeper zk = null;
    7. private String parentNode = "/servers";
    8. // 创建到 zk 的客户端连接
    9. public void getConnect() throws IOException {
    10. zk = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
    11. public void process(WatchedEvent watchedEvent) {
    12. }
    13. });
    14. }
    15. // 注册服务器
    16. public void registServer(String hostname) throws Exception {
    17. String create = zk.create("/servers/" + hostname, hostname.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
    18. System.out.println(hostname + " is online " + create);
    19. }
    20. // 业务功能
    21. public void business(String hostname) throws Exception {
    22. System.out.println(hostname + " is working ...");
    23. Thread.sleep(Long.MAX_VALUE);
    24. }
    25. public static void main(String[] args) throws Exception {
    26. // 1 获取 zk 连接
    27. Servers server = new Servers();
    28. server.getConnect();
    29. // 2 利用 zk 连接注册服务器信息
    30. server.registServer(args[0]);
    31. // 3 启动业务功能
    32. server.business(args[0]);
    33. }
    34. }

    Client代码:

    1. import org.apache.zookeeper.WatchedEvent;
    2. import org.apache.zookeeper.Watcher;
    3. import org.apache.zookeeper.ZooKeeper;
    4. import java.io.IOException;
    5. import java.util.ArrayList;
    6. import java.util.List;
    7. public class Client {
    8. private static String connectString="hadoop200:2181,hadoop201:2181,hadoop202:2181";
    9. private static int sessionTimeout = 2000;
    10. private ZooKeeper zk = null;
    11. private String parentNode = "/servers";
    12. // 创建到 zk 的客户端连接
    13. public void getConnect() throws IOException {
    14. zk = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
    15. public void process(WatchedEvent event) {
    16. // 再次启动监听
    17. try {
    18. getServerList();
    19. } catch (Exception e) {
    20. e.printStackTrace();
    21. }
    22. }
    23. });
    24. }
    25. // 获取服务器列表信息
    26. public void getServerList() throws Exception {
    27. // 1 获取服务器 子节点信息,并且对父节点进行监听
    28. List children = zk.getChildren(parentNode, true);
    29. // 2 存储服务器信息列表
    30. ArrayList servers = new ArrayList();
    31. // 3 遍历所有节点,获取节点中的主机名称信息
    32. for (String child : children) {
    33. byte[] data = zk.getData(parentNode + "/" + child,false, null);
    34. servers.add(new String(data));
    35. }
    36. // 4 打印服务器列表信息
    37. System.out.println(servers);
    38. }
    39. // 业务功能
    40. public void business() throws Exception{
    41. System.out.println("client is working ...");
    42. Thread.sleep(Long.MAX_VALUE);
    43. }
    44. public static void main(String[] args) throws Exception {
    45. // 1 获取 zk 连接
    46. Client client = new Client();
    47. client.getConnect();
    48. // 2 获取 servers 的子节点信息,从中获取服务器信息列表
    49. client.getServerList();
    50. // 3 业务进程启动
    51. client.business();
    52. }
    53. }

  • 相关阅读:
    疫情驱动医疗数字化新业态,ActiveReports强力助推医院LIMS系统升级换代!
    前端面试(1)——准备
    LeetCode C++ 88.合并两个有序数组
    python的多线程使用
    ThinkPHP 8.x MVC 数据库用户增加功能demo实现
    大二C#实现酒店管理系统(C端展示、前台操作、登记入住、入住管理、职位管理、公告系统等)
    winfrom .net 6使用EF Core,使用的是Code First代码先行
    Liunx常用命令
    【零基础入门JavaSE】数据类型与变量
    架构师成长之路|Redis实现延迟队列的三种方式
  • 原文地址:https://blog.csdn.net/qq_52135683/article/details/126781636