Zookeeper的watcher
在zookeeper中,有个很重要的概念就是watcher,可以看做是swing中的listener,只要你注册了watcher,那么当zk节点被操作时,你就可以通过watcher感知到。也可以理解为事件回调接口。
客户端通过
public class ZooKeeper{…}
进行远程连接和维护结构。
zookeeper watcher接口
1 | graph TD |
Watcher接口
watcher只有一个方法
abstract public void process(WatchedEvent event);
1 | public class WatchedEvent { |
客户端watcher
通过Zookeeper的构造函数注册watcher:
- public ZooKeeper(String connectString, int sessionTimeout, Watcher watcher)
- ZooKeeper(String connectString, int sessionTimeout, Watcher watcher,boolean canBeReadOnly)
- public ZooKeeper(String connectString, int sessionTimeout, Watcher watcher,long sessionId, byte[] sessionPasswd)
- public ZooKeeper(String connectString, int sessionTimeout, Watcher watcher,long sessionId, byte[] sessionPasswd, boolean canBeReadOnly)
wather注册后,服务器端会维护watcher,一旦watcher监听的节点被操作,将会发通知给客户端,客户端接收到通知后,会调用watcher的process方法。
zk的watcher只会起一次作用,一旦接收到通知调用后,这个watcher就失效了,如果还要监听此节点,需要重新注册watcher
服务端watcher维护
客户端注册watcher后,服务端将会维护已经注册到自己这端的watcher。
服务端会根据watcher监听的节点是否是父节点,将watcher分成2类。如果此节点没有子节点,那么只会监听本节点的变更,如果有子节点,那么会同时监听子节点和本节点的变更。
在服务端,watcher的维护分2个维度,1个是path到watcher,一个是watcher到path。
private final HashMap<String, HashSet
> watchTable =
new HashMap<String, HashSet>();
private final HashMap<Watcher, HashSet
> watch2Paths =
new HashMap<Watcher, HashSet>();
Watcher实现
zk服务端节点被操作,对应不同的EventType。服务端和客户端通过不同的数值代码表示不同的事件:
1 | case -1: return EventType.None; |
另外zk同样通过不同的状态码表示此时客户端与服务端的状态:
1 | case -1: return KeeperState.Unknown; |
当用户自定义实现watcher接口后,在监听的节点变更后,方法
void process(WatchedEvent event)
会被调用,用户在此方法中可以根据事件类型(EventType) 和 状态类型(KeeperState) 来判断需要进行什么样的业务逻辑。