ZooKeerper學習之Watcher

ZooKeeper爲咱們提供了用於監視結點變化的Watcher機方法制:java

一、能夠註冊Watcher的方法:getData()、exists()、getChildren()。咱們能夠經過查看ZooKeeper API看到node

getData方法:apache

 void	getData(String path, boolean watch, AsyncCallback.DataCallback cb, Object ctx)      
 byte[]	getData(String path, boolean watch, Stat stat)      
 void	getData(String path, Watcher watcher, AsyncCallback.DataCallback cb, Object ctx)  
 byte[]	getData(String path, Watcher watcher, Stat stat) 
exists方法:

 Stat	exists(String path, boolean watch) 
          Return the stat of the node of the given path.
 void	exists(String path, boolean watch, AsyncCallback.StatCallback cb, Object ctx) 
          The Asynchronous version of exists.
 Stat	exists(String path, Watcher watcher) 
          Return the stat of the node of the given path.
 void	exists(String path, Watcher watcher, AsyncCallback.StatCallback cb, Object ctx) 
          The Asynchronous version of exists.

getChildren方法:

 List<String>	getChildren(String path, boolean watch) 
          Return the list of the children of the node of the given path.
 void	getChildren(String path, boolean watch, AsyncCallback.Children2Callback cb, Object ctx) 
          The Asynchronous version of getChildren.
 void	getChildren(String path, boolean watch, AsyncCallback.ChildrenCallback cb, Object ctx) 
          The Asynchronous version of getChildren.
 List<String>	getChildren(String path, boolean watch, Stat stat) 
          For the given znode path return the stat and children list.
 List<String>	getChildren(String path, Watcher watcher) 
          Return the list of the children of the node of the given path.
 void	getChildren(String path, Watcher watcher, AsyncCallback.Children2Callback cb, Object ctx) 
          The Asynchronous version of getChildren.
 void	getChildren(String path, Watcher watcher, AsyncCallback.ChildrenCallback cb, Object ctx) 
          The Asynchronous version of getChildren.
 List<String>	getChildren(String path, Watcher watcher, Stat stat) 
          For the given znode path return the stat and children list.

二、能夠觸發Watcher的方法有:create()、delete()、setData()。經過查看API:

create方法:服務器

 String	create(String path, byte[] data, List<ACL> acl, CreateMode createMode) 
          Create a node with the given path.
 void	create(String path, byte[] data, List<ACL> acl, CreateMode createMode, AsyncCallback.StringCallback cb, Object ctx) 
          The Asynchronous version of create.

delete方法:session

 void	delete(String path, int version) 
          Delete the node with the given path.
 void	delete(String path, int version, AsyncCallback.VoidCallback cb, Object ctx) 
          The Asynchronous version of delete.

setData方法:

 Stat	setData(String path, byte[] data, int version) 
          Set the data for the node of the given path if such a node exists and the given version matches the version of the node (if the given version is -1, it matches any node's versions).
 void	setData(String path, byte[] data, int version, AsyncCallback.StatCallback cb, Object ctx) 
          The Asynchronous version of setData.

三、一個Watcher實例是一個回調函數,被調用一次之後就會被移除,若是還需觀察結點數據的變化,則還需再次註冊Watcher。

四、當咱們New ZooKeeper時,註冊的Watcher被稱爲default Watcher,它不是一次性的,只會對client的鏈接狀態變化作出反應。當發生CONNECTIONLOSS以後,只要在session_timeout時間以內可以再次連上(即不發生SESSION_EXPIRED),那麼這個鏈接註冊的watcher依然有效。app

五、同一個客戶端,對某一個節點註冊了屢次watcher,那麼只會收到一次通知。函數

六、一些操做對應的事件類型:this

Event for "/path"code

 Event for "/path/child"blog

Create("/path",...)

 EventType.NodeCreated

/

Delete("/path",...)

EventType.Deleted

/

setData("/path")

EventType.NodeDataChanged

/

Create("/path/child")

EventType.NodeChildrenChanged

EventType.NodeCreated

Delete("/path/child")

EventType.NodeChildrenChanged

EventType.NodeDeleted

setData("/path/child")

/

EventType.NodeDataChanged


七、事件類型與Watcher的對應關係:

event for "/path"

Default watcher

Exists("/path")

getData("/path")

getChildren("/path")

EventType.None

EventType.NodeCreated

EventType.NodeDeleted

EventType.NodeDataChanged

EventType.NodeChildrenChanged


一個小例子:

package org.apache.zookeeper.test;

import java.io.IOException;

import org.apache.log4j.PropertyConfigurator;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;



public class Demo {

    public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
        
    	// 建立一個與服務器的鏈接
        ZooKeeper zk = new ZooKeeper("192.168.11.201:2181", 6000, new Watcher() {
            // 監控全部被觸發的事件
        	/**
        	 * EventType:
        	 * None
        	 * NodeCreated
        	 * NodeChildrenChanged
        	 * NodeDataChanged
        	 * NodeDeleted
        	 */
            public void process(WatchedEvent event) {
                System.out.println("EVENT:" + event.getType());
            }
        });

        // 查看根節點
        System.out.println("ls / => " + zk.getChildren("/", true));

        // 建立一個目錄節點
        if (zk.exists("/node", true) == null) {
            zk.create("/node", "this is a znode".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            System.out.println("create /node this is a znode");
            // 查看/node節點數據
            System.out.println("get /node => " + new String(zk.getData("/node", false, null)));
            // 查看根節點
            System.out.println("ls / => " + zk.getChildren("/", true));
        }

        // 建立一個子目錄節點
        if (zk.exists("/node/app1", true) == null) {
            zk.create("/node/app1", "this is app1".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            System.out.println("create /node/app1 app1");
            // 查看node節點
            System.out.println("ls /node => " + zk.getChildren("/node", true));
        }

        // 修改節點數據
        if (zk.exists("/node", true) != null) {
            zk.setData("/node", "the data is changed".getBytes(), -1);
            // 查看/node節點數據
            System.out.println("get /node => " + new String(zk.getData("/node", false, null)));
        }

        // 刪除節點
        if (zk.exists("/node/app1", true) != null) {
            zk.delete("/node/app1", -1);
            zk.delete("/node", -1);
            // 查看根節點
            System.out.println("ls / => " + zk.getChildren("/", true));
        }

        // 關閉鏈接
        zk.close();
    }
}
相關文章
相關標籤/搜索