Zookeeper學習筆記九之 同步實現主節點選舉
阿新 • • 發佈:2018-12-11
同步實現主節點選舉
為了確保同一時間只有一個主節點程序處於活躍狀態,我們使用ZooKeeper來實現簡單的群首選舉演算法。這個演算法中,所有的節點都嘗試建立/master節點,但是隻有一個成功,這個成功的程序成為主節點。接下來是程式碼實現
package com.my.service; import java.io.IOException; import java.util.Random; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.ZooDefs; import org.apache.zookeeper.Watcher.Event.KeeperState; import org.apache.zookeeper.ZooKeeper; import org.apache.zookeeper.CreateMode; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.KeeperException.NoNodeException; import org.apache.zookeeper.KeeperException.NodeExistsException; import org.apache.zookeeper.data.Stat; public class MyZookeeper { private ZooKeeper zooKeeper; private String hostPort; private Random random = new Random(47); private String serverId = Integer.toString(random.nextInt()); boolean isMaster = false; public MyZookeeper(String hostPort) { this.hostPort = hostPort; } // 建立一個zk連線監視點,列印斷開連線日誌資訊 Watcher watcher = new Watcher() { public void process(WatchedEvent event) { // 如果監控到與服務端連線斷開,列印日誌 if (KeeperState.Disconnected.equals(event.getState())) { System.out.println("Zookeeper Disconnected!客戶端與ZooKeeper伺服器連線斷開!"); } } }; // 連線到zk服務端 public void startZk() throws IOException { zooKeeper = new ZooKeeper(hostPort, 15000, watcher); } public void stopZk() throws InterruptedException { zooKeeper.close(); } public boolean checkMaster() { while (true) { try { Stat stat = new Stat(); //通過獲取/master節點的資料來檢查活動主節點 byte data[] = zooKeeper.getData("/master", false, stat); isMaster = new String(data).equals(serverId); return true; } catch (NoNodeException e) { return false; } catch (Exception e) { e.printStackTrace(); } } } public void runForMaster() throws InterruptedException { while (true) { try { //建立成功,將會成為主節點 zooKeeper.create("/master", serverId.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL); isMaster = true; break; } catch (NodeExistsException e) { isMaster = false; } catch (KeeperException e) { e.printStackTrace(); } if (checkMaster()) { break; } } } public static void main(String[] args) throws IOException, InterruptedException { MyZookeeper myZookeeper = new MyZookeeper("127.0.0.1:2181"); myZookeeper.startZk(); myZookeeper.runForMaster(); if (myZookeeper.isMaster) { System.out.println("我是主節點"); Thread.sleep(60000); } else { System.out.println("其他節點已經成為了主節點"); } myZookeeper.stopZk(); } }