Zookeeper 提供的了分布式数据的公布/订阅功能,通过 Watch 机制来实现这样的分布式的通知功能。


Zookeeper 同意client向server注冊一个Watch监听。当服务端的一些指定的事件触发了这个Watch 。就会向指定的client发送一个事件通知来实现分布式通知。
整个Watch的注冊和通知过程如图:
Zookeeper的 Watcher 机制主要包含client现成、client WatchManager、Zookeeperserver三部分,详细流程是:client 向Zookeeper注冊的同一时候。把Watcher对象存储在client的WatchManager中,当Zookeeperserver端触发Watcher事件后,会向client发送通知。client线程从WatchManager中取出相应的Watcher对象运行回掉逻辑。

client注冊Watcher
可用在创建一个client实例时,向构造方法中传入一个默认的Watcher对象,也能够在调用 getData() , getChildren() , exist() 三个接口向 Zookeeper server注冊Watcher。不管使用哪种方式注冊。原理都是一致的。 这里已 getData接口说明:

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

在向 getData 接口注冊 Watcher 后。client首先会对当前client请求 request 进行标记。将其置为“使用 Watcher监听”,同一时候会封装一个 Watcher 的注冊对象 WatcherRegistration 对象。用于临时保存数据节点路径和Watcher的相应关系。详细逻辑代码:

public Stat getData(final String path, Watcher watcher , Stat stat){
     ..........
     WatcherRegistration wrt = null ;
     if(watcher !=null){
          wrt = new DataWatchRegistration(watcher,path);
     }
     ......
     request.setWatche(watcher!=null) ;//------注意此处兴许会用到
     ReplyHeader r = cnxn.submitRequest(h,request,response,wrt);

在Zookeeper中,Packet 能够被看做是一个最小的通信协议单元。用于client和server端之间进行网络传输,不论什么一个须要传输的对象都要被包装成 Packet 对象进行传输。由于 ClientCnxn 中的 WatcherRegistration 又会被封装到 Packet 中去,然后放入发送队列中等待client发送。

Packet queuePacket(RequestHeader h , ReplyHeader r , Record reqest , Record response, AsyncCallback cb ,String clientPath , String serverPath , Object ctx , WatcherRegistration wrt){
     .......
     synchronized(outgoingqueue){
          packet = new Packet(h,r,request,response,wrt) ;
          .........
          outgoingqueue.add(packet);
     }
....
}

随后,Zookeeper client会向服务端发送这个请求,同一时候等待服务端的返回。完毕请求发送后,会由client SendThread 线程的 readResponse 方法接受来自服务端的响应。finishPacket 方法会从 Packet 中取出相应的 Watcher 并注冊到ZkManager中去,代码逻辑:
     
private void finishPacket(Packet p){
     if(p.watcherRegistration != null){
          p.watcherRegistration.register(p.replyHeader.getErr());
     }
.......
}

如今把 Watcher 对象从 WatchRegistration 对象中取出来:
     
protected Map<String,HashSet<Watcher>> getWatchers(int rc){
     
     return watchManager.dataWatches ;

}

public void register(int rc){
     if(shouldAddWatch(rc)){
          Map<String,HashSet<Watcher>> watches = getWatchers(rc) ;
  synchronized(watches){
     
     Set<Watcher> watchers = watches.get(clientPath) ;
     if(watchers ==null){
            watchers  =new HashSet<Watcher>();
            watches.put(clientPath,watchers);
   }
             watchers.add(watcher);
     .........
}
在上面的register 方法中会吧临时存放的 watcher 对象转交给 ZKWatcherManager , 并终于保存到dataWatchers 中 ,dataWatchers , ZKWatcherManager 都是 Map<String,Set<Watcher>> 类型的数据结构,用于把数据节点的路径和Watcher对象一一映射后保存起来。

   

在上面的流程中,WatcherRegistration 在底层的网络序列化究竟层的字节数组中。















Watcher 实现机制之client注冊的更多相关文章

  1. 一个简单RPC框架是怎样炼成的(VI)——引入服务注冊机制

    开局篇我们说了.RPC框架的四个核心内容 RPC数据的传输. RPC消息 协议 RPC服务注冊 RPC消息处理 接下来处理RPC服务的注冊机制.所谓注冊机制,就是Server须要声明支持哪些rpc方法 ...

  2. Windows Azure Mobiles Services实现client的登录注冊

    下文仅仅是简单实现,client以Android端的实现为例: 用户表Account: package com.microsoft.ecodrive.model; public class Accou ...

  3. Eureka 的 Application Service client的注冊以及执行演示样例

            Eureka 服务器架起来了(关于架设步骤參考博客<Linux 下 Eureka 服务器的部署>),如今怎样把我们要负载均衡的服务器(也就是从 Application Cl ...

  4. 从注冊流程 分析怎样安全退出多个Activity 多种方式(附DEMO)

    前言 因为一个同学问到我怎样依照一个流程走好之后回到首页.我曾经看到过4个解决方式,后来发现有做个记录和总结的必要,就写了这篇博文. (之前看小强也写过一篇,这里通过自身的分析完整的总结一下下面6种方 ...

  5. Android应用程序注冊广播接收器(registerReceiver)的过程分析

    前面我们介绍了Android系统的广播机制,从本质来说,它是一种消息订阅/公布机制,因此,使用这样的消息驱动模型的第一步便是订阅消息:而对Android应用程序来说,订阅消息事实上就是注冊广播接收器, ...

  6. 基于Servlet、JSP、JDBC、MySQL的一个简单的用户注冊模块(附完整源代码)

    近期看老罗视频,做了一个简单的用户注冊系统.用户通过网页(JSP)输入用户名.真名和password,Servlet接收后通过JDBC将信息保存到MySQL中.尽管是个简单的不能再简单的东西,但麻雀虽 ...

  7. Android Binder分析二:Natvie Service的注冊

    这一章我们通过MediaPlayerService的注冊来说明怎样在Native层通过binder向ServiceManager注冊一个service,以及client怎样通过binder向Servi ...

  8. android binder 机制二(client和普通server)

    在讲它们之间的通信之前,我们先以MediaServer为例看看普通Server进程都在干些什么. int main() { -- // 获得ProcessState实例 sp<ProcessSt ...

  9. spring揭秘 读书笔记 二 BeanFactory的对象注冊与依赖绑定

    本文是王福强所著<<spring揭秘>>一书的读书笔记 我们前面就说过,Spring的IoC容器时一个IoC Service Provider,并且IoC Service Pr ...

随机推荐

  1. LeetCode1-5

    Leetcode1: Given an array of integers, return indices of the two numbers such that they add up to a ...

  2. [LUOGU] P1466 集合 Subset Sums

    题目描述 对于从1到N (1 <= N <= 39) 的连续整数集合,能划分成两个子集合,且保证每个集合的数字和是相等的.举个例子,如果N=3,对于{1,2,3}能划分成两个子集合,每个子 ...

  3. LVS-NAT负载均衡PHP应用(Wordpress、Discuz)

    1 实验拓扑 2 需求 RS-01和RS-02对外提供WEB服务. RS-01搭建LAMP,PHP通过http模块方式提供. RS-02搭建LAMP,PHP通过fpm方式提供. RS-01和RS-02 ...

  4. Python之购物车

    Python之购物车 msg_list = [ ['iphone',8888], ['coffe',38], ['book',90], ['Tesla',100000], ['RR',10000000 ...

  5. python 列表(二)

     列表的其他操作 count 用于统计列表中某个元素出现的次数 Eg: extend 把一个列表添加到另一个列表里面 Index 输出元素的位置即根据内容索引位置 Reverse 把列表元素的位置倒过 ...

  6. Spider-scrapy 中的 xpath 语法与调试

    把setting中的机器人过滤设为False ROBOTSTXT_OBEY = False 1 语法 artcile 选取所有子节点 /article 选取根元素 artile article/a 选 ...

  7. WinMain名词解析

    WinMain程序名词解析 int WINAPI WinMain(HINSTANCE hInstance ,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nS ...

  8. Java 集合相关

    对整个体系做一个记录,并不涉及详细应用 Object类 1. 重写toString方法 System.out.println可以打印任何对象在于Object类拥有一个方法 public String ...

  9. 图解使用IDEA创建第一个Java程序HelloWorld

    前几次给大家分享了怎么在自己的电脑上配置 java 环境,准备工作做好了,我们就要开始我们真正的编码学习了.下面介绍使用 IDEA 创建我们的第一个 HelloWorld 程序. 1.打开 IDEA, ...

  10. openstack -> openinfra

    https://www.openstack.org/assets/software/projectmap/openstack-map.pdf