通知机制:
客户端注册监听他关心的目录节点,当目录节点发生变化(数据改变、被删除、子目录节点增加删除)时,zookeeper会通知客户端
Session:
客户端使用某种语言绑定创建一个服务的句柄时,就建立了一个zookeeper会话。会话建立后,句柄处于CONNECTING状态,客户端会试图连接到组成zookeeper服务的某个服务器,连接成功则进入到CONNECTED状态。通常操作中句柄将处于这两个状态之一。如果发生不可恢复的错误,如会话过期、身份鉴定失败、应用显示关闭,则句柄进入到closed状态。
Watch:
客户端可以在每个znode节点上设置一个观察,如果被观察服务端的znode节点有变更,那么watch就会被触发,这个watch所属的客户端将接受到一个通知包 告知节点已经发生变化,把相应的事件通知给设置watch的client端。
也即异步回调的触发机制
watch事件理解:
一次触发(one-time-trigger):当数据有了变化时,zookeeperserver向客户端发送一个watch,他是一次性动作,即触发一次就不再有效,类似一次性纸杯。
只监控一次
如果想继续watch的话,需要客户端重新设置watcher。所以如果你得到一个watch事件且想在将来的变化继续得到通知,必须设置另一个watch。发往客户端:watches是异步发往客户端的,zookeeper提供了一个顺序保证,在看到watch事件之前绝不会看到变化,这样不同客户端看到的是一致性的顺序:
在导致watch事件触发的操作成功码返回到达客户端之前,事件可能在去客户端的路上,但是可能不会到达客户端。观察事件是异步的发送给观察者(客户端)的,zookeeper会保证次序:在收到观察事件之前,客户端不会看到已经为之设置观察的节点的改动。网络延迟或者其他因素可能会让不同的客户端在不同的时间收到观察事件和操作的返回码,这里的要点是:不同客户端看到的事情都有一致的次序为数据设置watch:数据观察和子节点观察,getData()和exists()设置数据观察,getChildren()设置子节点观察。
setData()将为znode触发数据观察,成功的create()将为新创建的节点触发数据观察,为其父节点触发子节点观察,成功的delete()将会为被删除的节点触发数据观察以及子节点观察(因为节点不能再有子节点了),为其父节点出发子节点观察
观察维护在zookeeper服务器中,客户端连接到新的服务器时,所有的会话事件将被触发,同服务器断开连接期间不会收到观察;客户端重新连接时,如果需要,先前已经注册的观察将被重新注册和触发。有一种情况下观察事件将丢失:对还没有创建的节点设置存在观察,而在断开连接期间创建节点,然后删除
一次触发:
public class ZkWatchDemo {
private final static Logger logger = Logger.getLogger(ZkDemo.class);
private final static String CONNECT_STRING = "192.168.0.139:2181";
private final static int SESSION_TIMEOUT = 50*1000;
//获得zookeeper实例
public ZooKeeper startZk() throws IOException {
return new ZooKeeper(CONNECT_STRING, SESSION_TIMEOUT, event -> {
logger.info("A " + event.toString());
});
}
//关闭zookeeper
public void stopZk(ZooKeeper zooKeeper)