浅析ZooKeeper的Watcher机制

Watcher是实现ZooKeeper的发布/订阅功能最核心的一个角色。当我们需要对ZooKeeper的某一个节点的变化做出后续处理时,就需要使用到Watcher。

ZooKeeper的Watcher机制,总的来说可以分为三个流程:client注册Watcher,server处理Watcher,client回调Watcher。接下来我将从上面三个流程分析Watcher是如何工作的。


Client注册Watcher

Client中有一个ZKWatcher Manager用来保存所有注册的Watcher 。

1.使用默认的构造函数注册:

public ZooKeeper(String connectString, int sessionTimeout, Watcher watcher)

这个Watcher 会作为整个会话期间的默认的Watcher,保存在defaultWathcer。
2.使用getData、exist方法注册,这里以getData为例子进行分析,getData有两个重载的方法:

public byte[] getData(String path, boolean watch, Stat stat)

这个boolean 变量表示是否注册默认的Watcher

public byte[] getData(final String path, Watcher watcher, Stat stat)

public byte[] getData(final String path, Watcher watcher, Stat stat)
        throws KeeperException, InterruptedException
     {
        final String clientPath = path;
        PathUtils.validatePath(clientPath);

        // the watch contains the un-chroot path
        //WatchRegistration 用来保存Watch和path的对应关系
        WatchRegistration wcb = null;
        if (watcher != null) {
            wcb = new DataWatchRegistration(watcher, clientPath);
        }

        final String serverPath = prependChroot(clientPath);

        RequestHeader h = new RequestHeader();
        h.setType(ZooDefs.OpCode.getData);
        GetDataRequest request = new GetDataRequest();
        request.setPath(serverPath);
        //对于request请求进行标记,表示此请求需要注册watcher 
        request.setWatch(watcher != null);
        GetDataResponse response = new GetDataResponse();
        //设置ReplyHeader
        ReplyHeader r = cnxn.submitRequest(h, request, response, wcb);
        if (r.getErr() != 0) {
            throw KeeperException.create(KeeperException.Code.get(r.getErr()),
                    clientPath);
        }
        if (stat != null) {
            DataTree.copyStat(response.getStat(), stat);
        }
        return response.getData();
    }

WatchRegistration 用来保存Watch和path的对应关系的。在ZooKeeper中,最小的通信单元是Packet,所以需要把WatchRegistration用Packet进行包装。包装成Packet以后,放入队列中等待发送。

Client发送这个Packet以后,由SendThread线程的readResponse()来接受响应,然后调用finishPacket(packet)方法从packet中提出Wathcer,并且注册到ZKWatcherManager中。

private void 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值