Zookeeper的API中的所有读操作:getData、getChildren和exists,均可以选择在读取的znode节点上设置监视点。使用监视点机制,需要实现Watcher接口类,实现其中的方法如下:
public void process(WatchedEvent event);
WatchedEvent数据结构包括以下信息:
- Zookeeper会话状态(KeeperState):Disconnected、SyncConnected、AuthFailed、ConnectedReadOnly、SaslAuthenticated和Expired
- 事件类型(EventType):NodeCreated、NodeDeleted、NodeDataChanged、NodeChildrenChanged和None
- 如果事件类型不是None时,返回一个znode路径
其中前三个事件类型只涉及单个znode节点,第四个事件类型涉及监视的znode节点的子节点。使用None不是表示无事件发生,而是Zookeeper的会话状态发生了变化。
监视点有两种类型:数据监视点和子节点监视点。创建、删除或设置一个znode节点的数据都会触发数据监视点,exists和getData这两个操作可以设置数据监视点。只有getChildren操作可以设置子节点监视点,这种监视点只有在znode子节点创建或删除时才被触发。对于每种事件类型,可以通过以下调用设置监视点:
- NodeCreated:通过exists调用设置一个监视点
- NodeDeleted:通过exists或getData调用设置监视点
- NodeDataChanged:通过exists或getData调用设置监视点
- NodeChildrenChanged:通过getChildren调用设置监视点
当创建一个Zookeeper对象,需要传递一个默认的Watcher对象,Zookeeper客户端使用这个监视点来通知应用Zookeeper状态的变化情况,如会话状态的变化。对于ZooKeeper节点的事件的通知,可以使用默认的监视点,也可以单独实现一个。例如,getData调用有两种方式设置监视点:
public byte[] getData(final String path, Watcher watcher, Stat stat);
public byte[] getData(String path, boolean watch, Stat stat);
两个方法第一个参数均为znode节点,第一个方法传递一个新的Watcher对象,第二个方法则告诉客户端使用默认的监视点,只需要在调用时将第二个参数传递true。
stat入參為Stat类型的实例化对象,ZooKeeper使用该对象返回指定的path参数的znode节点信息。Stat结构包括znode节点的属性信息,如该znode节点的上次更新(zxid)的时间戳,以及该znode节点的子节点数。
对于监视点的一个重要问题是,一旦设置监视点就无法移除。要想移除一个监视点,只有两个方法,一是触发这个监视点,二是使其会话被关闭或过期