当节点发生变化时,通过watcher机制,可以让客户端得到通知,watcher需要实现org.apache.ZooKeeper.Watcher接口。节点的状态变化主要包含如下
public class ZWatcher implements Watcher { @Override public void process(WatchedEvent event) { // TODO Auto-generated method stub if(event.getType() == EventType.NodeCreated){ System.out.println("创建节点"); } if(event.getType() == EventType.NodeDataChanged){ System.out.println("节点改变"); } if(event.getType() == EventType.NodeChildrenChanged){ System.out.println("子节点节点改变"); } if(event.getType() == EventType.NodeDeleted){ System.out.println("节点删除"); } } }
需要注意的是watcher是一次性的,也就是处理完一次状态变化之后需要重新注册watcher,这点很让人抓狂。这个特性也使得在处理时间上和重新加载上watcher这段时间发生的节点状态变化将无法感知。
通常会抛出下面两种异常:
org.apache.zookeeper.KeeperException$ConnectionLossException: KeeperErrorCode = NodeExists for /root
at org.apache.zookeeper.KeeperException.create(KeeperException.java:119)
at org.apache.zookeeper.KeeperException.create(KeeperException.java:51)
at org.apache.zookeeper.ZooKeeper.create(ZooKeeper.java:783)
客户机与其中一台服务器socket连接出现异常,连接丢失
org.apache.zookeeper.KeeperException.SessionExpiredException: KeeperErrorCode = Session expired
客户端的session已经超时sessionTimeout,未进行任何操作。
KeeperException.ConnectionLossException:异常可以通过重试进行处理,客户端会根据初始化Zookeeper时传递的服务列表,自动尝试下一节点。这段时间内,服务端节点就会丢失
KeeperException.SessionExpiredException:异常不能通过重试进行解决,需要应用重新创建一个新的客户端(new ZooKeeper()),这是所有的watcher和EPHEMRAL节点都将消失