Curator 事件有两种模式,一种是标准的观察模式,一种是缓存监听模式。标准的监听模式是使用Watcher 监听器。第二种缓存监听模式引入了一种本地缓存视图的Cache机制,来实现对Zookeeper服务端事件监听。
Cache事件监听可以理解为一个本地缓存视图与远程Zookeeper视图的对比过程。Cache提供了反复注册的功能。Cache是一种缓存机制,可以借助Cache实现监听。简单来说,Cache在客户端缓存了znode的各种状态,当感知到zk集群的znode状态变化,会触发event事件,注册的监听器会处理这些事件。
Watcher 监听器比较简单,只有一种。Cache事件监听的种类有3种Path Cache,Node Cache,Tree Cache。
1、写在前面
org.apache.zookeeper.ZooKeeper类 主要方法列表
方法名称 | 描述 |
---|---|
String create(final String path, byte data[], List acl, CreateMode createMode) | 创建一个znode节点;参数: 路径、 znode内容,ACL(访问控制列表)、 znode创建类型 |
void delete(final String path, int version) | 删除一个znode节点;参数: 路径、版本号;如果版本号与znode的版本号不一致,将无法删除,是一种乐观加锁机制;如果将版本号设置为-1,不会去检测版本,直接删除; |
Stat exists(final String path, Watcher watcher) | 判断某个znode节点是否存在;参数: 路径、Watcher(监视器);当这个znode节点被改变时,将会触发当前Watcher |
Stat exists(String path, boolean watch) | 判断某个znode节点是否存在;参数: 路径、并设置是否监控这个目录节点,这里的 watcher 是在创建 ZooKeeper 实例时指定的 watcher |
Stat setData(final String path, byte data[], int version) | 设置某个znode上的数据;参数: 路径、数据、版本号;如果为-1,跳过版本检查 |
byte[] getData(final String path, Watcher watcher, Stat stat) | 获取某个znode上的数据;参数: 路径、监视器、数据版本等信息 |
List getChildren(final String path, Watcher watcher) | 获取某个节点下的所有子节点;参数: 路径、监视器;该方法有多个重载 |
2、Watcher 标准的事件处理器
在ZooKeeper中,接口类Watcher用于表示一个标准的事件处理器,其定义了事件通知相关的逻辑,包含KeeperState和EventType两个枚举类,分别代表了通知状态和事件类型。
Watcher接口定义了事件的回调方法:process(WatchedEvent event)。定义一个Watcher的实例很简单,代码如下:
Watcher w = new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
log.info("监听器watchedEvent:" + watchedEvent);
}
};
使用Watcher监听器实例的方式也很简单,在Curator的调用链上,加上usingWatcher方法即可,代码如下:
byte[] content = client.getData()
.usingWatcher(w).forPath(workerPath);
一个Watcher监听器在向服务端完成注册后,当服务端的一些事件触发了这个Watcher,那么就会向指定客户端发送一个事件通知,来实现分布式的通知功能。客户收到服务器的通知后,Curator 会封装一个WatchedEvent 事件实例,传递给监听器的回调方法process(WatchedEvent event)。
WatchedEvent包含了三个基本属性:
(1)通知状态(keeperState)
(2)事件类型(EventType)
(3)节点路径(path)
注意,WatchedEvent并不是直接从ZooKeeper集群直接传递过来的事件实例,而是Curator 封装过的事件实例。WatchedEvent类型没有实现序列化接口java.io.Serializable,因此不能用于网络传输。ZooKeeper集群直接网络传输传递过来的事件实例是啥呢? 是一个WatcherEvent类型的实例,这个传输实例和Curator 封装过的WatchedEvent实例,在名称上有一个字母之差,而且功能也是一样的,都表示的是同一个事物,都是对一个服务端事件的封装。
因此,这里只讲Curator 封装过的WatchedEvent实例,接下来汇总下ZooKeeper中最常见的几