ZooKeeper Watcher监听机制
Watcher是ZooKeeper实现实时通知的核心机制。
Watcher监听机制
一次性触发特性:
Java
注册Watcher → 事件触发 → Watcher失效
需要重新注册才能继续监听
Watcher特点:
| 特点 | 说明 |
|---|---|
| 一次性 | 触发后失效 |
| 异步 | 回调异步执行 |
| 顺序 | 按事件顺序触发 |
事件类型:
| 事件 | 说明 |
|---|---|
| None | 连接状态变化 |
| NodeCreated | 节点创建 |
| NodeDeleted | 节点删除 |
| NodeDataChanged | 数据修改 |
| NodeChildrenChanged | 子节点变化 |
注册方式:
Java
// 读操作时注册Watcher
zk.getData("/path", watcher, stat);
zk.getChildren("/path", watcher);
zk.exists("/path", watcher);
回调处理:
Java
Watcher watcher = new Watcher() {
public void process(WatchedEvent event) {
String path = event.getPath();
EventType type = event.getType();
// 处理事件
// 重新注册Watcher
zk.getData(path, this, null);
}
};
注意:Watcher触发后必须重新注册才能继续监听。
数据变更监听
节点数据监听:
Java
// 监听数据变化
zk.getData("/config/db", new Watcher() {
public void process(WatchedEvent event) {
if (event.getType() == EventType.NodeDataChanged) {
// 读取新数据
byte[] newData = zk.getData(event.getPath(), this, null);
// 更新配置
updateConfig(newData);
}
}
}, stat);
子节点监听:
Java
// 监听子节点变化
zk.getChildren("/services/order", new Watcher() {
public void process(WatchedEvent event) {
if (event.getType() == EventType.NodeChildrenChanged) {
// 重新获取子节点列表
List<String> children = zk.getChildren(event.getPath(), this);
// 更新服务列表
updateServiceList(children);
}
}
});
监听场景:
| 场景 | 监听方式 |
|---|---|
| 配置变更 | getData监听数据 |
| 服务发现 | getChildren监听子节点 |
| 分布式锁 | exists监听节点删除 |
TreeCache持续监听:
text
// Curator TreeCache解决一次性问题
TreeCache cache = TreeCache.newBuilder(client, "/config").build();
cache.start();
cache.getListenable().addListener((client, event) -> {
// 持续监听,无需重新注册
if (event.getType() == TreeCacheEvent.Type.NODE_UPDATED) {
// 处理数据变更
}
});
监听注意事项:
| 问题 | 解决方案 |
|---|---|
| 一次性触发 | 回调中重新注册 |
| 事件丢失 | 比对版本号确认 |
| 重连后失效 | 会话恢复重新注册 |
提示:TreeCache/Curator实现持续监听,简化开发。
要点总结
- Watcher一次性触发,需重新注册
- 事件类型:数据变更、节点创建删除、子节点变化
- getData监听数据,getChildren监听子节点
- 回调中需重新注册继续监听
- TreeCache解决一次性监听问题
- 会话重连后Watcher需重新注册
📝 发现内容有误?点击此处直接编辑