Zookeeper之Zookeeper的Client的分析【转】
Zookeeper之Zookeeper的Client的分析
1)几个重要概念
ZooKeeper:客户端入口
Watcher:客户端注册的callback
ZooKeeper.SendThread: IO线程
ZooKeeper.EventThread: 事件处理线程,处理各类消息callback
ClientCnxnSocketNIO:继承自ClientCnxnSocket,专门处理IO
2)zookeeper初始化
应用提供watch实例
实例化zookeeper
实例化socket,默认使用ClientCnxnSocketNIO,可通过zookeeper.clientCnxnSocket配置定制
实例化ClientCnxn
实例化SendThread
实例化EventThread
启动zookeeper
启动SendThread
连接服务器(见SendThread.startConnect)
产生真正的socket,见ClientCnxnSocketNIO.createSock
向select注册一个OP_CONNECT事件并连接服务器,由于是非阻塞连接,此时有可能并不会立即连上,如果连上就会调用SendThread.primeConnection初始化连接来注册读写事件,否则会在接下来的轮询select获取连接事件中处理
复位socket的incomingBuffer
连接成功后会产生一个connect型的请求发给服务,用于获取本次连接的sessionid
进入循环等待来自应用的请求,如果没有就根据时间来ping 服务器
启动EventThread
开始进入无限循环,从队列waitingEvents中获取事件,如果没有就阻塞等待
3)以一个请求为例以 zk.exists("/root", false)为例
客户端线程
构造一个exists类型的请求,请求类型见ZooDefs.OpCode
将请求构造成一个Packet,并将该packet放入outgoingQueue
唤醒select
阻塞等待结果
SendThread
通过select 轮询判断是否有socket准备好,如果能读就读,能写就写
此时socket准备好写了 ,就从outgoingQueue获取packet, 将packet发送到服务端
一旦发送了一个完整的packet,就将packet从outgoingQueue移除
最后将packet加入到pendingQueue
再次select轮询看是否有响应数据,如果有首先都去4个字节的响应头(包含响应的长度信息),然后在下一次遍历中都去响应体
都到响应将packet从pendingQueue移除
如果该请求packet带有一个callback,那么会将此packet放入waitingEvents队列,让EventThread去处理
最后会调用p.notifyAll()解锁,于是应用线程从阻塞中出来
如果使用了带callback 的exists,EventThread会干活
4)小结
4.1)
SendThread也并非完全对应与请求/响应模式,SendThread也会接受到节点变化的通知,此时客户端变成了服务端
4.2)时间和超时的控制
ClientCnxnSocket作为ClientCnxnSocketNIO的父类,
有3个关键的时间字段
now :每次轮询select之前更新,或者发生错误是在catch段中更新为当前时间
lastHeard:在读取了响应,包括上面提到的connect型请求和常规命令型请求的响应以及完成网络连接时更新为当前时间
lastSend:每次发送完ping 命令和请求以及完成网络连接时更新为当前时间
有下面几个超时设置
sessionTimeout:zookeeper初始化时设置的
readTimeout:sessionTimeout * 2 / 3
connectTimeout:sessionTimeout / hostProvider.size(); //hostProvider.size()为zookeeper服务器个数
getIdleRecv():now - lastHeard
getIdleSend():now - lastSend
SessionTimeout的计算
如果没有完成连接to=connectTimeout - getIdleRecv()
如果完成连接to=readTimeout - getIdleRecv()
如果to<=0 就会抛出SessionTimeoutException
4.3)什么时候ping
计算timeToNextPing = readTimeout / 2-getIdleSend()
如果timeToNextPing <= 0,发送ping请求(只是将ping请求放入outgoingQueue,并不发生IO)
4.4)select阻塞多久
如果上述的0<timeToNextPing<to,那么阻塞时长为timeToNextPing,否则为to
如果有写请求,select会被唤醒
4.5)sendThread的工作原理
该线程作为zookeeper客户端的核心部分专门负责IO处理
计算select timeout(上面提到的to)
检查空闲时间,有可能抛出SessionTimeoutException或者发送ping
使用select轮询,获取网络事件(连接、读、写)也就是这3类
如果是连接,做连接处理
如果读,过程如下
读取消息头,4个字节,头包含了消息体的字节数
读 取消息体,分为两个大类消息,连接型消息“connect”和非连接型消息“header”,前者上面提到过就是连接完成之后发的一种消息,用于确定 sessionid, 另外前者会调用sendThread.onConnected,后者会调用sendThread.readResponse
非连接型消息有分为几类
ping 消息
auth认证消息
订阅的消息,即各种变化的通知,比如子节点变化、节点内容变化,由服务器推过来的消息 ,获取到这类消息或通过eventThread.queueEvent将消息推入事件队列
客户端命令的response,如果此消息带有callback着通过eventThread.queuePacket推入事件队列,否者唤醒阻塞的应用线程,注意到客户端命令都会有阻塞版本和异步版本(带callback)
如果是写,就从outgoingQueue获取packet,写入网络
4.6)请求中的Watcher和StatCallback的差别
两个都是callback,两者都由EventThread,但后者控制调用线程是否会阻塞等待响应
4.7)IO模型
如图
没有使用传统连接池,会和zookeeper集群中的一台相连
单IO线程(NIO)+事件线程,很标准的NIO模式
Zookeeper之Zookeeper的Client的分析【转】的更多相关文章
- zookeeper安装使用及工作原理分析
1. Zookeeper概念简介 Zookeeper是一个分布式协调服务:就是为用户的分布式应用程序提供协调服务,它是集群的管理者,监视着集群中各个节点的状态,根据节点提交的反馈进行下一步合理操作. ...
- ZooKeeper源码阅读——client(二)
原创技术文章,转载请注明:转自http://newliferen.github.io/ 如何连接ZooKeeper集群 要想了解ZooKeeper客户端实现原理,首先需要关注一下客户端的使用方式, ...
- ZooKeeper日志与快照文件简单分析
有用过Zookeeper的都知道zoo.cfg配置文件中有dataDir配置项用于存储数据,不过可能有些人不太清楚这个目录具体存储的是那些数据,默认情况下这个目录是用于存储Log(事务日志)与Snap ...
- ZooKeeper 01 - 什么是ZooKeeper + 部署ZooKeeper集群
目录 1 什么是ZooKeeper 2 ZooKeeper的功能 2.1 配置管理 2.2 命名服务 2.3 分布式锁 2.4 集群管理 3 部署ZooKeeper集群 3.1 下载并解压安装包 3. ...
- 【ZooKeeper】ZooKeeper入门流水记
单机模式 下载zookeeper的包 wget http://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.4.9/zookeeper-3.4.9.ta ...
- zookeeper(3) zookeeper的实践及原理
一.基于java API初探zookeeper的使用 (1)建立连接 public static void main(String[] args) { //NOT_CONNECTED-->CON ...
- zookeeper:一.zookeeper集群安装
1.zookeeper简介2.安装zookeeper2.1 安装环境准备2.2 安装zookeeper2.2.1.解压zookeeper压缩包到/opt/zookeeper2.2.2.编辑zookee ...
- Dubbo+Zookeeper(一)Zookeeper初识
前面花了一段时间去学习SpringCloud的相关知识,主要是理解微服务的概念并使用SpringCloud的一系列组件实现微服务落地.学习这些组件本身是简单的,跟着操作一遍基本就会了,这也得益于Spr ...
- Zookeeper - 什么是Zookeeper,以及zookeeper的安装(1)
Zookeeper 什么是Zookeeper? 官网传送门 ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的 ...
随机推荐
- [OpenCV-Python] OpenCV 中的图像处理 部分 IV (三)
部分 IVOpenCV 中的图像处理 OpenCV-Python 中文教程(搬运)目录 19 Canny 边缘检测 目标 • 了解 Canny 边缘检测的概念 • 学习函数 cv2.Canny() 1 ...
- kms可用激活服务器地址|kms可用激活服务器分享
kms可用激活服务器地址|kms可用激活服务器分享 kms可用激活服务器地址都有哪些呢?使用kms激活服务器激活windows和office是微软提供的激活方式之一.kms激活服务器普遍由个人或企 ...
- POJ2417 Discrete Logging【BSGS】(模板题)
<题目链接> 题目大意: P是素数,然后分别给你P,B,N三个数,然你求出满足这个式子的L的最小值 : BL== N (mod P). 解题分析: 这题是bsgs算法的模板题. #incl ...
- Linux学习之文件系统常用命令(七)
Linux文件系统常用命令 目录 df命令 du命令 fsck命令 dump2fs命令 df命令 df命令 统计文件系统的占有情况,分区用了多少空间,还剩多少空间 df [选项] [挂载点] 选项: ...
- Spring Boot 项目实战(一)Maven 多模块项目搭建
一.前言 最近公司项目准备开始重构,框架选定为 Spring Boot ,本篇主要记录了在 IDEA 中搭建 Spring Boot Maven 多模块项目的过程. 二.软件及硬件环境 macOS S ...
- js基础梳理-究竟什么是变量对象,什么是活动对象?
首先,回顾下上篇博文中js基础梳理-究竟什么是执行上下文栈(执行栈),执行上下文(可执行代码)?的执行上下文的生命周期: 3.执行上下文的生命周期 3.1 创建阶段 生成变量对象(Variable o ...
- 【xxl-job】轻松实现分布式定时任务demo实例
[项目描述]前段时间专门独立了一个spring boot服务,用于做和第三方erp系统的对接工作.此服务的第一个需求工作就是可以通过不同的规则,设置不同的定时任务,从而获取erp系统的商品数据.所以, ...
- Web大前端面试题-Day7
1. 你能描述一下渐进增强和优雅降级之间的不同吗? 定义: 优雅降级(graceful degradation): 一开始就构建站点的完整功能, 然后针对浏览器测试和修复 渐进增强(progressi ...
- CSDN 博客 美化 个性化
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha ========= ======== <a href=" http:// ...
- 11.5 正睿停课训练 Day16
目录 2018.11.5 正睿停课训练 Day16 A 道路规划(思路) B 逻辑判断(枚举 位运算/DP 高维前缀和) C 区间(贪心/树状数组) 考试代码 A B C 2018.11.5 正睿停课 ...