“Zookeeper:watcher 事件机制原理”的版本间差异

来自Wikioe
跳到导航 跳到搜索
(建立内容为“category:Zookeeper == 关于 ==”的新页面)
 
无编辑摘要
第2行: 第2行:


== 关于 ==
== 关于 ==
监视是一种简单的机制,使客户端收到关于ZooKeeper集合中的更改的通知。客户端可以在读取特定znode时设置Watches。Watches会向注册的客户端发送任何znode(客户端注册表)更改的通知。
* Znode更改是与znode相关的数据的修改或znode的子项中的更改。
* watches只触发一次就失效。
*: 如果客户端想要再次通知,则必须通过另一个读取操作来完成。
* 当连接会话过期时,客户端将与服务器断开连接,相关的watches也将被删除。
== 原理 ==
zookeeper 的 watcher 机制,可以分为四个过程:
# 客户端注册 watcher;
# 服务端处理 watcher;
# 服务端触发 watcher 事件;
# 客户端回调 watcher。
* 其中“客户端注册 watcher”有三种方式,调用客户端 API 可以分别通过 '''getData'''、'''exists'''、'''getChildren''' 实现。
以 exists 方法举例说明其原理:
: <syntaxhighlight lang="java" highlight="">
public class WatcherDemo implements Watcher {
    static ZooKeeper zooKeeper;
    static {
        try {
            zooKeeper = new ZooKeeper("192.168.3.39:2181", 4000,new WatcherDemo());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
   
    @Override
    public void process(WatchedEvent event) {
        System.out.println("eventType:"+event.getType());
        if(event.getType()==Event.EventType.NodeDataChanged){
            try {
                zooKeeper.exists(event.getPath(),true);
            } catch (KeeperException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
   
    public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
        String path="/watcher";
        if(zooKeeper.exists(path,false)==null) {
            zooKeeper.create("/watcher", "0".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        }
        Thread.sleep(1000);
        System.out.println("-----------");
        // true表示使用zookeeper实例中配置的watcher
        Stat stat=zooKeeper.exists(path,true);
        System.in.read();
    }
}
</syntaxhighlight>
: 运行完程序,控制台显示:
: [[File:Zookeeper:watcher机制:示例1.png|600px]]
: 此时启动 zookeeper 命令行终端,查看并且删除 watcher 节点:
: [[File:Zookeeper:watcher机制:示例2.png|600px]]
: IDE 控制台输出,触发了节点删除事件:
: [[File:Zookeeper:watcher机制:示例3.png|600px]]
=== 源码分析 ===
客户端发送请求给服务端是通过 TCP 长连接建立网络通道,底层默认是通过 '''java 的 NIO''' 方式,也可以配置 '''netty''' 实现方式。
: [[File:Zookeeper:watcher机制:客户端请求流程.png|600px]]
注册 watcher 监听事件流程图:
: [[File:Zookeeper:watcher机制:注册 watcher 监听事件流程.png|600px]]
# 客户端发送事件通知请求:
#:
#:

2021年5月14日 (五) 19:45的版本


关于

监视是一种简单的机制,使客户端收到关于ZooKeeper集合中的更改的通知。客户端可以在读取特定znode时设置Watches。Watches会向注册的客户端发送任何znode(客户端注册表)更改的通知。

  • Znode更改是与znode相关的数据的修改或znode的子项中的更改。
  • watches只触发一次就失效。
    如果客户端想要再次通知,则必须通过另一个读取操作来完成。
  • 当连接会话过期时,客户端将与服务器断开连接,相关的watches也将被删除。

原理

zookeeper 的 watcher 机制,可以分为四个过程:

  1. 客户端注册 watcher;
  2. 服务端处理 watcher;
  3. 服务端触发 watcher 事件;
  4. 客户端回调 watcher。
  • 其中“客户端注册 watcher”有三种方式,调用客户端 API 可以分别通过 getDataexistsgetChildren 实现。


以 exists 方法举例说明其原理:

public class WatcherDemo implements Watcher {
    static ZooKeeper zooKeeper;
    static {
        try {
            zooKeeper = new ZooKeeper("192.168.3.39:2181", 4000,new WatcherDemo());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    @Override
    public void process(WatchedEvent event) {
        System.out.println("eventType:"+event.getType());
        if(event.getType()==Event.EventType.NodeDataChanged){
            try {
                zooKeeper.exists(event.getPath(),true);
            } catch (KeeperException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
        String path="/watcher";
        if(zooKeeper.exists(path,false)==null) {
            zooKeeper.create("/watcher", "0".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        }
        Thread.sleep(1000);
        System.out.println("-----------");
        // true表示使用zookeeper实例中配置的watcher
        Stat stat=zooKeeper.exists(path,true);
        System.in.read();
    }
}
运行完程序,控制台显示:
Zookeeper:watcher机制:示例1.png
此时启动 zookeeper 命令行终端,查看并且删除 watcher 节点:
Zookeeper:watcher机制:示例2.png
IDE 控制台输出,触发了节点删除事件:
Zookeeper:watcher机制:示例3.png

源码分析

客户端发送请求给服务端是通过 TCP 长连接建立网络通道,底层默认是通过 java 的 NIO 方式,也可以配置 netty 实现方式。

Zookeeper:watcher机制:客户端请求流程.png

注册 watcher 监听事件流程图:

Zookeeper:watcher机制:注册 watcher 监听事件流程.png


  1. 客户端发送事件通知请求: