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

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

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

8.1.1 需求描述

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

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

8.1.2 设计思路

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

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]);

     }

}



上一篇:FTP工作方式


下一篇:常用Linux系统优化脚本