学习笔记:Zookeeper 应用案例(上下线动态感知)

    xiaoxiao2023-08-12  117

    1、Zookeeper 应用案例(上下线动态感知)

    8.1 案例1——服务器上下线动态感知

    8.1.1 需求描述

    某分布式系统中,主节点可以有多台,可以动态上下线

    任意一台客户端都能实时感知到主节点服务器的上下线

    8.1.2 设计思路

    8.1.3 代码开发

    1、客户端实现

    package cn.com.toto.zkonlineoroffline;

     

    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 DistributedClient {

        private static final String connectString = "192.168.106.80:2181,192.168.106.81:2181,192.168.106.82:2181";

        private static final int sessionTimeout = 2000;

         private static final String parentNode = "/servers";

         // 注意:加volatile的意义何在?

         private volatile List<String> serverList;

         private ZooKeeper zk = null;

     

         /**

          * 创建到zk的客户端连接

          *

          * @throws Exception

          */

         public void getConnect() throws Exception {

             zk = new ZooKeeper(connectString, sessionTimeout, new Watcher() {

                  @Override

                  public void process(WatchedEvent event) {

                       // 收到事件通知后的回调函数(应该是我们自己的事件处理逻辑)

                       try {

                           //重新更新服务器列表,并且注册了监听

                           getServerList();

     

                       } catch (Exception e) {

                       }

                  }

             });

         }

     

         /**

          * 获取服务器信息列表

          *

          * @throws Exception

          */

         public void getServerList() throws Exception {

             // 获取服务器子节点信息,并且对父节点进行监听

             List<String> children = zk.getChildren(parentNode, true);

     

             // 先创建一个局部的list来存服务器信息

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

             for (String child : children) {

                  // child只是子节点的节点名

                  byte[] data = zk.getData(parentNode + "/" + child, false, null);

                  servers.add(new String(data));

             }

             // 把servers赋值给成员变量serverList,已提供给各业务线程使用

             serverList = servers;

            

             //打印服务器列表

             System.out.println(serverList);

         }

     

         /**

          * 业务功能

          *

          * @throws InterruptedException

          */

         public void handleBussiness() throws InterruptedException {

             System.out.println("client start working.....");

             Thread.sleep(Long.MAX_VALUE);

         }

        

         public static void main(String[] args) throws Exception {

             // 获取zk连接

             DistributedClient client = new DistributedClient();

             client.getConnect();

             // 获取servers的子节点信息(并监听),从中获取服务器信息列表

             client.getServerList();

     

             // 业务线程启动

             client.handleBussiness();

         }

    }

    2、服务器端实现

    package cn.com.toto.zkonlineoroffline;

     

    import java.util.concurrent.CountDownLatch;

     

    import org.apache.zookeeper.CreateMode;

    import org.apache.zookeeper.WatchedEvent;

    import org.apache.zookeeper.Watcher;

    import org.apache.zookeeper.ZooKeeper;

    import org.apache.zookeeper.Watcher.Event.KeeperState;

    import org.apache.zookeeper.ZooDefs.Ids;

    import org.apache.zookeeper.data.Stat;

     

    public class DistributedServer {

         private static final String CONNECT_STRING = "192.168.106.80:2181,192.168.106.81:2181,192.168.106.82:2181";

         private static final int SESSION_TIME_OUT = 2000;

         private static final String PARENT_NODE = "/servers";

     

         private ZooKeeper zk = null;

        

         CountDownLatch countDownLatch = new CountDownLatch(1);

     

         /**

          * 创建到zk的客户端连接

          *

          * @throws Exception

          */

         public void getConnect() throws Exception {

             zk = new ZooKeeper(CONNECT_STRING, SESSION_TIME_OUT, new Watcher() {

                  @Override

                  public void process(WatchedEvent event) {

                       if(event.getState()==KeeperState.SyncConnected){

                           countDownLatch.countDown();

                       }

                  }

             });

             countDownLatch.await();

         }

     

         /**

          * 向zk集群注册服务器信息

          *

          * @param hostname

          * @throws Exception

          */

         public void registerServer(String hostname) throws Exception {

             Stat exists = zk.exists(PARENT_NODE, false);

             if(exists==null) zk.create(PARENT_NODE, null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);

             String path = zk.create(PARENT_NODE + "/server", hostname.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);

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

         }

     

         /**

          * 业务功能

          *

          * @throws InterruptedException

          */

         public void handleBussiness(String hostname) throws InterruptedException {

             System.out.println(hostname + "start working.....");

             Thread.sleep(Long.MAX_VALUE);

         }

     

         public static void main(String[] args) throws Exception {

             DistributedServer server = new DistributedServer();

             // 获取zk连接

             server.getConnect();

     

             // 利用zk连接注册服务器信息(主机名)

             server.registerServer(args[0]);

     

             // 启动业务功能

             server.handleBussiness(args[0]);

         }

    }

    相关资源:七夕情人节表白HTML源码(两款)
    最新回复(0)