基于库zkclient 的leader选举代码实现

利用了zookeeper临时节点,在当连接或session断掉时被删除这一特性来做选举。(简单简单互斥锁

查了下网上的做法。

大致流程:

<1>判定是否存在/wzgtest路径

<2>如果不存在,那么试图创建一个节点znode(Ephemeral Path)(path = /wzgtest,data=client id)

<2.1>创建成功,标识自己是leader。

<2.2>创建不成功(包括异常)标识自己是slave。

<3>监听/wzgtest节点的数据变化。节点移除(zookeeper连接断开,session超时)时,重走<1>重新进行选举。

具体代码详见附件。

该代码只是实现,并未进行包装优化。

  1 import java.net.InetAddress;
  2 import java.net.UnknownHostException;
  3 
  4 import org.I0Itec.zkclient.IZkDataListener;
  5 import org.I0Itec.zkclient.ZkClient;
  6 
  7 /**
  8  * @author 作者 王志刚
  9  * @version 创建时间:2016年8月18日 下午7:13:49
 10  * @Description:  zkleader选举
 11  */
 12 public class ZKLeaderElect {
 13 
 14     public boolean isLeader = false;
 15     private ZkClient zkClient = null;
 16     private String path = "XXXXX";
 17     private String hostInfo = "initString";
 18 
 19     public void initZKLeaderElect(String zkServers, String path, String s) {
 20         zkClient = new ZkClient(zkServers, 10000, 10000);
 21         this.path = path;
 22         try {
 23             hostInfo = InetAddress.getLocalHost().toString();
 24         } catch (UnknownHostException e) {
 25         }
 26         hostInfo = s;
 27     }
 28 
 29     /**
 30     * 选举leader
 31     *
 32     */
 33     public void tryLeader() {
 34         if (!zkClient.exists(path)) {
 35             try {
 36                 zkClient.createEphemeral(path, hostInfo);
 37                 isLeader = true;
 38                 System.out.println(hostInfo + "  成为leader了");
 39             } catch (Exception e) {
 40                 System.out.println(hostInfo+"成为leader失败");
 41                 e.printStackTrace();
 42                 isLeader = false;
 43             }
 44         }
 45     }
 46 
 47     /**
 48     * 监听指定节点的数据变化
 49     *
 50     */
 51     public void testListener() throws InterruptedException {
 52         // 监听指定节点的数据变化
 53         zkClient.subscribeDataChanges(path, new IZkDataListener() {
 54             public void handleDataChange(String s, Object o) throws Exception {
 55 //                System.out.println(hostInfo+"说:");
 56 //                System.out.println("node data changed!");
 57 //                System.out.println("node=>" + s);
 58 //                System.out.println("data=>" + o);
 59 //                System.out.println("--------------");
 60 //                tryLeader();
 61             }
 62 
 63             public void handleDataDeleted(String s) throws Exception {
 64                 System.out.println(hostInfo+"说:");
 65                 System.out.println("node data deleted!");
 66                 System.out.println("s=>" + s);
 67                 System.out.println("--------------");
 68                 tryLeader();
 69             }
 70         });
 71 
 72         System.out.println(hostInfo + " ----- ready!");
 73 
 74     }
 75 
 76     public static void main(String[] args) throws InterruptedException {
 77         ZKLeaderElect zk1 = new ZKLeaderElect();
 78         zk1.initZKLeaderElect("10.1.51.221:7605", "/wzgtest","1");
 79 
 80         ZKLeaderElect zk2 = new ZKLeaderElect();
 81         zk2.initZKLeaderElect("10.1.51.221:7605", "/wzgtest","2");
 82 
 83         ZKLeaderElect zk3 = new ZKLeaderElect();
 84         zk3.initZKLeaderElect("10.1.51.221:7605", "/wzgtest","3");
 85 
 86         zk1.tryLeader();
 87         zk2.tryLeader();
 88         zk3.tryLeader();
 89         zk1.testListener();
 90         zk2.testListener();
 91         zk3.testListener();
 92         int i = 0;
 93         // junit测试时,防止线程退出
 94         while (true) {
 95             Thread.sleep(1000);
 96             i++;
 97             if(i % 5 == 0){
 98                 if(zk1.isLeader){
 99                     zk1.zkClient.close();
100                     System.out.println("1 关闭了");
101                     zk1.isLeader = false;
102                 }
103                 if(zk2.isLeader){
104                     zk2.zkClient.close();
105                     System.out.println("2 关闭了");
106                     zk2.isLeader = false;
107                 }
108                 if(zk3.isLeader){
109                     zk3.zkClient.close();
110                     System.out.println("3 关闭了");
111                     zk3.isLeader = false;
112                 }
113             }
114             System.out.println("1"+zk1.isLeader+"       2:"+zk2.isLeader+"   3:"+zk3.isLeader);
115             
116         }
117     }
118 }
原文地址:https://www.cnblogs.com/aoeiuv/p/5868152.html