Zookeeper研究之Watcher和一些應用場景

前段時間項目中用到Zookeeper,前人已經搭建好環境、封裝好業務邏輯、只須要配置一下就能夠用。簡單但不夠深刻,有點‘紙上得來終覺淺,絕知此事要躬行’的感受。

Zookeeper環境很是容易搭建,只須要注意下配置文件,在myid文件中寫上配置文件中的編號便可,參考:http://attend.iteye.com/blog/1454212

    查看ZK源代碼,發現網絡通訊用的是NIO實現的,創建客戶端鏈接時,必定要等到狀態爲已鏈接時才能夠進行下一步操做,代碼實現藉助鎖的邏輯來實現。如:

    final CountDownLatch countDownLatch = new CountDownLatch(1);

    ZK 很大的用處是ZK集羣上的每個變化均可以通知到自定義的Watchcer實現。利用ZK集羣的高可用性(2X+1臺機器,容忍X臺機器掛掉)。而且ZK有一套如文件系統通常的能夠增刪改查的數據模型(Znode)。運用這套模型來實現自定義服務。有點抽象,畫個圖,以下:

zk

客戶端鏈接到ZK的物理集羣中,集羣中維護了Znode模型,客戶端對znode進行操做,由Zk維護Znode模型的一致性和高可用性,而且能夠對Znode節點增刪改查數據。也能夠用給Znode模型上添加新的節點。添加節點若是須要監控這個節點須要調用

zooKeeper.exists(path, true);方法,這個方法做用是:若是存在path並設置watch爲true,監控起來,這樣就能夠把針對這個path的變化 通知到watcher.(明白這點很是重要,初學者常犯並無watcher這個path,就想獲取到針對這個path的事件)。

來段測試代碼:
package com.jcloud.zk.taokepper.reader;

import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
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;

public class ZkReader {


	public static void main(String args[]) throws IOException, KeeperException,
			InterruptedException {

		//藉助於該方法實現剛開始鏈接等待,鏈接好後,才容許下一步的邏輯。
		final CountDownLatch countDownLatch = new CountDownLatch(1);
		
		final ZooKeeper zooKeeper = new ZooKeeper("10.28.174.199:2181;10.28.174.79:2181", 10000,
				new Watcher() {
					@Override
					public void process(WatchedEvent event) {
						System.out.println("event." +event);
						if (null != event) {
							if (event.getState() == KeeperState.SyncConnected) {
								//若是鏈接好了,能夠下一步操做
								countDownLatch.countDown();
								System.out.println("---> created...");
							}
						}
					}
				});
		countDownLatch.await();
		//等到鏈接完成後後,開始下一步。
		System.out.println("--->");
		AtomicInteger increInt = new AtomicInteger();
		
		String path="/2testnode0";
		while (true) {
			Thread.sleep(1000L);
			//zooKeeper.create(path, "ttttt".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
//要在這個Path上作watcher
			zooKeeper.exists(path, true);
			//修改節點數據,觸發watcher
			zooKeeper.setData(path, (path+increInt.getAndAdd(1)).getBytes(), -1);
			zooKeeper.setData(path, (path+increInt.getAndAdd(1)).getBytes(), -1);
			System.out.println((path+increInt.getAndAdd(1)));	
		}
	}
}

Zk有些經典使用場景,好比配置項推送,作法是,多個客戶端鏈接到ZK集羣中,監控同一個Znode,只要一個客戶端改變了這個Znode,其餘監控的客戶端均可以收到相應的消息。

還能夠用來作服務高可用性,最經典的用法是服務器起來的話,建立一個臨時Znode,服務掛掉後刪除這個Znode,其餘監控到這個Znode的客戶端也能夠收到服務是否可用的消息。

還能夠用來作選舉場景,多個客戶端建立同一個Znode,誰建立成功了誰就是老大。關於這個Znode的一致性就讓ZK集羣完成吧。

整體感受ZK確實提供是一款不錯的一致性、高可用性工具。試着去用好它。
相關文章
相關標籤/搜索