当前位置: 首页 > news >正文

计算机应用技术网站开发/seo教程论坛

计算机应用技术网站开发,seo教程论坛,金蝶软件官网下载,张家港网站开发培训广告代理Zookeeper的watch机制 概况:大体上讲 ZooKeeper 实现的方式是通过客服端和服务端分别创建有观察者的信息列表。客户端调用 getData、exist 等接口时,首先将对应的 Watch 事件放到本地的 ZKWatchManager 中进行管理。服务端在接收到客户端的请求后根据请求…

Zookeeper的watch机制

概况:大体上讲 ZooKeeper 实现的方式是通过客服端和服务端分别创建有观察者的信息列表。客户端调用 getData、exist 等接口时,首先将对应的 Watch 事件放到本地的 ZKWatchManager 中进行管理。服务端在接收到客户端的请求后根据请求类型判断是否含有 Watch 事件,并将对应事件放到 WatchManager 中进行管理。

在事件触发的时候服务端通过节点的路径信息查询相应的 Watch 事件通知给客户端,客户端在接收到通知后,首先查询本地的 ZKWatchManager 获得对应的 Watch 信息处理回调操作。这种设计不但实现了一个分布式环境下的观察者模式,而且通过将客户端和服务端各自处理 Watch 事件所需要的额外信息分别保存在两端,减少彼此通信的内容。大大提升了服务的处理性能。

具体如下:

客户端 Watch 注册实现过程
我们先看一下客户端的实现过程,在发送一个 Watch 监控事件的会话请求时,ZooKeeper 客户端主要做了两个工作:

  1. 标记该会话是一个带有 Watch 事件的请求
  2. 将 Watch 事件存储到 ZKWatchManager

我们以 getData 接口为例。当发送一个带有 Watch 事件的请求时,客户端首先会把该会话标记为带有 Watch 监控的事件请求,之后通过 DataWatchRegistration 类来保存 watcher 事件和节点的对应关系:

public byte[] getData(final String path, Watcher watcher, Stat stat){...WatchRegistration wcb = null;if (watcher != null) {wcb = new DataWatchRegistration(watcher, clientPath);}RequestHeader h = new RequestHeader();request.setWatch(watcher != null);...GetDataResponse response = new GetDataResponse();ReplyHeader r = cnxn.submitRequest(h, request, response, wcb);}

之后客户端向服务器发送请求时,是将请求封装成一个 Packet 对象,并添加到一个等待发送队列outgoingQueue 中:

public Packet queuePacket(RequestHeader h, ReplyHeader r,...) {Packet packet = null;...packet = new Packet(h, r, request, response, watchRegistration);...outgoingQueue.add(packet); ...return packet;
}

最后,ZooKeeper 客户端就会向服务器端发送这个请求,完成请求发送后。调用负责处理服务器响应SendThread 线程类中的 readResponse 方法接收服务端的回调,并在最后执行 finishPacket()方法将 Watch 注册到 ZKWatchManager 中:

private void finishPacket(Packet p) {int err = p.replyHeader.getErr();if (p.watchRegistration != null) {p.watchRegistration.register(err);}...
}

服务端 Watch 注册实现过程

介绍完客户端对 Watch 请求的发送过程,下面我们来看一下服务端是如何处理一个 Watch 事件。

Zookeeper 服务端处理 Watch 事件基本有 2 个过程:

  • 解析收到的请求是否带有 Watch 注册事件
  • 将对应的 Watch 事件存储到 WatchManager

下面我们分别对这 2 个步骤进行分析:

当 ZooKeeper 服务器接收到一个客户端请求后,首先会对请求进行解析,判断该请求是否包含 Watch 事件。这在 ZooKeeper 底层是通过 FinalRequestProcessor 类中的 processRequest 函数实现的。当 getDataRequest.getWatch() 值为 True 时,表明该请求需要进行 Watch 监控注册。并通过 zks.getZKDatabase().getData 函数将 Watch 事件注册到服务端的 WatchManager 中。

public void processRequest(Request request) {
...
byte b[] =                zks.getZKDatabase().getData(getDataRequest.getPath(), stat,getDataRequest.getWatch() ? cnxn : null);
rsp = new GetDataResponse(b, stat);
..
}

服务端 Watch 事件的触发过程

在客户端和服务端都对 watch 注册完成后,我们接下来看一下在 ZooKeeper 中触发一个 Watch 事件的底层实现过程:
上图中列出了客户端在不同会话状态下,相应的在服务器节点所能支持的事件类型。例如在客户端连接服务端的时候,可以对数据节点的创建、删除、数据变更、子节点的更新等操作进行监控。

我们以 setData 接口即“节点数据内容发生变更”事件为例。在 setData 方法内部执行完对节点数据的变更后,会调用 WatchManager.triggerWatch 方法触发数据变更事件。

public Stat setData(String path, byte data[], ...){Stat s = new Stat();DataNode n = nodes.get(path);...dataWatches.triggerWatch(path, EventType.NodeDataChanged);return s;}

下面我们进入 triggerWatch 函数内部来看看他究竟做了哪些工作。首先,封装了一个具有会话状态、事件类型、数据节点 3 种属性的 WatchedEvent 对象。之后查询该节点注册的 Watch 事件,如果为空说明该节点没有注册过 Watch 事件。如果存在 Watch 事件则添加到定义的 Wathcers 集合中,并在 WatchManager 管理中删除。最后,通过调用 process 方法向客户端发送通知

Set<Watcher> triggerWatch(String path, EventType type...) {WatchedEvent e = new WatchedEvent(type,KeeperState.SyncConnected, path);Set<Watcher> watchers;synchronized (this) {watchers = watchTable.remove(path);...for (Watcher w : watchers) {Set<String> paths = watch2Paths.get(w);if (paths != null) {paths.remove(path);}}}for (Watcher w : watchers) {if (supress != null && supress.contains(w)) {continue;}w.process(e);}return watchers;}

客户端回调的处理过程

知道了服务器端 Watch 事件的触发过程后,我们来看一下客户端接收到通知后如何进行操作的。

客户端使用 SendThread.readResponse() 方法来统一处理服务端的相应。首先反序列化服务器发送请求头信息 replyHdr.deserialize(bbia, "header"),并判断相属性字段 xid 的值为 -1,表示该请求响应为通知类型。在处理通知类型时,首先将己收到的字节流反序列化转换成 WatcherEvent 对象。接着判断客户端是否配置了 chrootPath 属性,如果为 True 说明客户端配置了 chrootPath 属性。需要对接收到的节点路径进行 chrootPath 处理。最后调用 eventThread.queueEvent( )方法将接收到的事件交给 EventThread 线程进行处理

if (replyHdr.getXid() == -1) {...WatcherEvent event = new WatcherEvent();event.deserialize(bbia, "response");...if (chrootPath != null) {String serverPath = event.getPath();if(serverPath.compareTo(chrootPath)==0)event.setPath("/");...event.setPath(serverPath.substring(chrootPath.length()));...}WatchedEvent we = new WatchedEvent(event);...eventThread.queueEvent( we );
}

接下来我们来看一下 EventThread.queueEvent() 方法内部的执行逻辑。其主要工作分为 2 点:
第 1 步按照通知的事件类型,从 ZKWatchManager 中查询注册过的客户端 Watch 信息。客户端在查询到对应的 Watch 信息后,会将其从 ZKWatchManager 的管理中删除。因此这里也请你多注意,客户端的 Watcher 机制是一次性的,触发后就会被删除。

public Set<Watcher> materialize(...)
{Set<Watcher> result = new HashSet<Watcher>();...switch (type) {...case NodeDataChanged:case NodeCreated:synchronized (dataWatches) {addTo(dataWatches.remove(clientPath), result);}synchronized (existWatches) {addTo(existWatches.remove(clientPath), result);}break;....}return result;
}

完成了第 1 步工作获取到对应的 Watcher 信息后,将查询到的 Watcher 存储到 waitingEvents 队列中,调用 EventThread 类中的 run 方法会循环取出在 waitingEvents 队列中等待的 Watcher 事件进行处理。

public void run() {try {isRunning = true;while (true) {Object event = waitingEvents.take();if (event == eventOfDeath) {wasKilled = true;} else {processEvent(event);}if (wasKilled)synchronized (waitingEvents) {if (waitingEvents.isEmpty()) {isRunning = false;break;}}}...
}

最后调用 processEvent(event) 方法来最终执行实现了 Watcher 接口的 process()方法。

private void processEvent(Object event) {...if (event instanceof WatcherSetEventPair) {WatcherSetEventPair pair = (WatcherSetEventPair) event;for (Watcher watcher : pair.watchers) {try {watcher.process(pair.event);} catch (Throwable t) {LOG.error("Error while calling watcher ", t);}}}
}
http://www.lbrq.cn/news/1744867.html

相关文章:

  • 网站主编 做啥/设计培训班学费一般多少
  • 公众号开发服务招标公告/seo的方法
  • 北京梦创义网站建设/上海抖音推广
  • 网站建设成果/指数基金
  • wordpress 家教/官网排名优化
  • 网络优化工程师需要具备哪些能力/南平网站seo
  • 网站招代理/平面设计培训费用一般是多少
  • 网站开发有哪些内容/酒泉网站seo
  • 国内网站设计公司/需要一个网站
  • 网站开发实用技术 代码/推广手段有哪些
  • intitle 郑州网站建设/磁力蜘蛛种子搜索
  • 微信群投票网站怎么做/电脑培训课程
  • 博彩类网站开发教程/网络推广员是干什么的
  • 手机网站建设行业现状/百度 个人中心首页
  • 江苏质监站网站做资料/抖音seo软件工具
  • 网站建设内容策略/广告投放价目表
  • 网站的功能板块/网页制作咨询公司
  • 政府网站集约化建设情况报告/制作网站的网址
  • 县级网站/大数据营销推广精准粉
  • 兰州网站建设价/聊城seo整站优化报价
  • 打造网站品牌/app推广员好做吗
  • 单站点网站/东莞建设网
  • 十大黄冈网站排行榜/免费推广app
  • 网站建设还流行吗/如何获取网站的seo
  • 云南旅游网站建设公司/广告联盟大全
  • 有没有做彩票直播的网站/深度搜索
  • 网站备案流程教程/网络营销和推广的方法
  • asp.net做网站/百度竞价排名又叫什么
  • 苏州市网站优化/百度seo引流
  • 微信支付 企业网站/网站维护中是什么意思
  • 【27】MFC入门到精通——MFC 修改用户界面登录IP IP Address Control
  • Springboot集成SpringSecurity的介绍及使用
  • Spring Boot - Spring Boot 集成 MyBatis 分页实现 RowBounds
  • 网络编程(TCP连接)
  • HTML面试题
  • 穿透、误伤与回环——Redis 缓存防御体系的负向路径与治理艺术