1. 程式人生 > >Zookeeper學習筆記九之 同步實現主節點選舉

Zookeeper學習筆記九之 同步實現主節點選舉

同步實現主節點選舉

       為了確保同一時間只有一個主節點程序處於活躍狀態,我們使用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();
	}
}