zookeeper客户端与服务端交互流程源码解析

客户端发送请求和接收请求。

图1

zookeeper客户端与服务端交互流程源码解析_第1张图片

图1 zkCll.sh 启动时会调用zookeeperMain() 方法。古这是入口。

图2

zookeeper客户端与服务端交互流程源码解析_第2张图片

 图2 290行 new ZookeeperMain , 297行连接zk  

图3

 zookeeper客户端与服务端交互流程源码解析_第3张图片

图 3 277 判断zk的状态,  281行设置只读,  282行 new Zookeeper()

图4

zookeeper客户端与服务端交互流程源码解析_第4张图片

图4 445 行赋值watcher给默认的defaultWatcher. 447行对地址进行处理, 447行包装地址。

图5

zookeeper客户端与服务端交互流程源码解析_第5张图片

图5 如果 写多个地址的话zookeeper回随机选择一个地址连接,如果这个地址挂了,他会从其他的地址再从新选一个连接。 

图6

zookeeper客户端与服务端交互流程源码解析_第6张图片

图7

zookeeper客户端与服务端交互流程源码解析_第7张图片

图8

zookeeper客户端与服务端交互流程源码解析_第8张图片

图6 图7 图8 意思是 传进来的地址 以逗号截取,然后每一个地址再以":" 分号截取,封装到inetSocketAddressHolder类中,然后把 inetSocketAddressHolder 放在一个ArrayList中serverAddresses中。

图9

zookeeper客户端与服务端交互流程源码解析_第9张图片

图10

zookeeper客户端与服务端交互流程源码解析_第10张图片

图 9 图10没有做jut具体的事情,104行 打乱的意思(图10),换句话说就是随机地址连接。

图10

zookeeper客户端与服务端交互流程源码解析_第11张图片

图11

zookeeper客户端与服务端交互流程源码解析_第12张图片

ClientCnxSockNIO

图12

zookeeper客户端与服务端交互流程源码解析_第13张图片

图11 图12 1884行先拿 图12 的key 去配置文件中查找是否配置这个名字,如果没有配置ClientCnxSockNIO 的全类名,然后反射实例化返回。

图13

zookeeper客户端与服务端交互流程源码解析_第14张图片13

图13初始化Zookeeper参数值,创建两个线程。

图14

zookeeper客户端与服务端交互流程源码解析_第15张图片

图15

zookeeper客户端与服务端交互流程源码解析_第16张图片

 

图16

zookeeper客户端与服务端交互流程源码解析_第17张图片

图14,图15,图16 启动两个线程,SendThread 继承ZookeeperThread  这个线程。Zookeerper线程继承Thread线程。

图17

zookeeper客户端与服务端交互流程源码解析_第18张图片

zookeeper客户端与服务端交互流程源码解析_第19张图片

zookeeper客户端与服务端交互流程源码解析_第20张图片

zookeeper客户端与服务端交互流程源码解析_第21张图片zookeeper客户端与服务端交互流程源码解析_第22张图片

zookeeper客户端与服务端交互流程源码解析_第23张图片

 

zookeeper客户端与服务端交互流程源码解析_第24张图片

zookeeper客户端与服务端交互流程源码解析_第25张图片

 

图17-0

zookeeper客户端与服务端交互流程源码解析_第26张图片17-1

图17-1

zookeeper客户端与服务端交互流程源码解析_第27张图片

图17-2

zookeeper客户端与服务端交互流程源码解析_第28张图片

图17-3

zookeeper客户端与服务端交互流程源码解析_第29张图片

图17-4

zookeeper客户端与服务端交互流程源码解析_第30张图片

图17-5

zookeeper客户端与服务端交互流程源码解析_第31张图片

图17-6

zookeeper客户端与服务端交互流程源码解析_第32张图片

图17-7

zookeeper客户端与服务端交互流程源码解析_第33张图片

 

图17-8

zookeeper客户端与服务端交互流程源码解析_第34张图片

图17-9

zookeeper客户端与服务端交互流程源码解析_第35张图片

zookeeper客户端与服务端交互流程源码解析_第36张图片

zookeeper客户端与服务端交互流程源码解析_第37张图片

图17-9 80行如果还没有初始化,等待连接返回的结果图17-12。92行如果初始化完了,改为true 。94行  客户端发送后,如何响应呢,94行sendThread.readRespone() 用这个线程读取响应结果图17-15。

图17-10

zookeeper客户端与服务端交互流程源码解析_第38张图片

图17-11

zookeeper客户端与服务端交互流程源码解析_第39张图片

zookeeper客户端与服务端交互流程源码解析_第40张图片

图17-12

zookeeper客户端与服务端交互流程源码解析_第41张图片

zookeeper客户端与服务端交互流程源码解析_第42张图片

图17-12核心方法 为146行调用另一个线程的onConnected的方法图17-13

图17-13

zookeeper客户端与服务端交互流程源码解析_第43张图片

zookeeper客户端与服务端交互流程源码解析_第44张图片

图17-13  1312行如果连接成功 本地注册一个Watcher的None事件。

图17-14

zookeeper客户端与服务端交互流程源码解析_第45张图片

图17-15

zookeeper客户端与服务端交互流程源码解析_第46张图片

zookeeper客户端与服务端交互流程源码解析_第47张图片

zookeeper客户端与服务端交互流程源码解析_第48张图片

zookeeper客户端与服务端交互流程源码解析_第49张图片

zookeeper客户端与服务端交互流程源码解析_第50张图片

zookeeper客户端与服务端交互流程源码解析_第51张图片

zookeeper客户端与服务端交互流程源码解析_第52张图片4

图17-15  通过判断xid的值来分别处理,-2 ping的处理,-4验证,-1 客户端接收服务的的事件。 823行 packet的replyHeader的xid和replyHdr的xid一致时,把replyHdr的请求头信息从新封装到packet中,842行中,如果服务端返回信息,同样把新增加的服务端返回信息封装到 packet中. replyHdr是什么呢,是把从参数传入的流信息进行解析转换为replyHdr,此时这个replyHdr没有response信息。850行完成通知图17-16

图17-16

图17-16 完成唤醒操作。

 

图17 为SendThread 的run()方法。图17 图18  1044行 默认状态为未连接状态。如果不是关闭状态和验证失败状态就是活着的状态图19 ;1046行如果未连接,是第一次连接1047行的if判断. 会走1062行 ,从hostPovider选取一个地址,进行socket连接。 1100行为读取超时= 设置的超时时间 减去 当前时间距离上次读取时间(now -上次读取时间)<0 则认为是超时,或者,设置的连接事件 减去当前时间距离上次发送时间(now -上次发送时间)小于0认为连接超时则抛出异常sessionTimeOutException。然后try catch捕获异常,程序不会中止,继续执行while循环,1044行;当第一次connect()方法时 图17-1,图17-2,图17-3 方法 把isFirstConnect置为false,当抛出sessionTimeOutException 异常时,进入1047行到1053行睡眠一段时间。1062行 ,图17-4 默认超时情况下从新从其他的地址中选取一个地址,不会是上一次执行的地址,因为会采用取余数的方式,图17-4;图1115行连接成功,就返送ping.图17-5 ,和发送逻辑一致,只不过类型为OpCode.ping ;xid=-2. ; 1115行连接成功  后1145行 客户端发送数据 

zookeeper客户端与服务端交互流程源码解析_第53张图片

图17 到图17-14 总结; 首先1.初始化 SendThread线程 ,初始化 socket  ;  2.zookeeper 创建一条命令,然后这个命令加到 request  ,把Request 变成Packet ,最后放在outgoingQueue队列中。sendThread 线程中有一个while(){ 1.如果socket没有连接就去连接,2,如果socket连接成功了,客户端会发送一个ConnectRequest, 接受服务端返回的ConnectResponse(Envent.none)  3,如果连接成功,从outgoingQueue 队列中取出packet ,通过socket发送出去,同时,如果说 有结果。penedingqueue里面回去放等待结果的packet} 

图18

zookeeper客户端与服务端交互流程源码解析_第54张图片

图19

zookeeper客户端与服务端交互流程源码解析_第55张图片

图20

zookeeper客户端与服务端交互流程源码解析_第56张图片

zookeeper客户端与服务端交互流程源码解析_第57张图片

图20 995行 改变状态为 正在连接,conecting . 设置名字。999行到1018行不重要,1019行打印日志不重要。 1021行socket连接。

图21

zookeeper客户端与服务端交互流程源码解析_第58张图片

图22

zookeeper客户端与服务端交互流程源码解析_第59张图片

图23

zookeeper客户端与服务端交互流程源码解析_第60张图片

 

图24

zookeeper客户端与服务端交互流程源码解析_第61张图片

图23  连接socket  ClientCnxnSocket 接口 的 connect() 方法,他有唯一的实现类ClientCnxnSocketNIO的connect()方法图24.

  首先创建一个socket图25. 287行 注册一个socket图26.

图25

zookeeper客户端与服务端交互流程源码解析_第62张图片

图26

zookeeper客户端与服务端交互流程源码解析_第63张图片

图26  276行注册一个连接事件,277行 判断是不是立即连接成功,如果是调用primeConnection()方法。 

图27

zookeeper客户端与服务端交互流程源码解析_第64张图片

总结 ;

zookeeper客户端与服务端交互流程源码解析_第65张图片



图28-0 

图28-0 290行为执行完成以后,执行291行命令行的run()方法。  

图28

zookeeper客户端与服务端交互流程源码解析_第66张图片

zookeeper客户端与服务端交互流程源码解析_第67张图片

图28 314行,316行为java 的命令行实现类。332行为核心的实现类方法 图31。执行命令 图30命令行前缀对应的代码 图29;

图29

zookeeper客户端与服务端交互流程源码解析_第68张图片

图30

图31

zookeeper客户端与服务端交互流程源码解析_第69张图片

图31 如果命令不为空,加入命令,加入历史,处理命令。命令次数加1.重点是372行。

 

图32

zookeeper客户端与服务端交互流程源码解析_第70张图片

图33

zookeeper客户端与服务端交互流程源码解析_第71张图片

zookeeper客户端与服务端交互流程源码解析_第72张图片

zookeeper客户端与服务端交互流程源码解析_第73张图片

zookeeper客户端与服务端交互流程源码解析_第74张图片

图33 689行创建命令 如果有-e,-s 为创建临时有序节点,如果 -e 就是临时节点,-s就是持久节点顺序 704行返回权限列表图34 ,707行调用zk 创建节点。709行打印命令 。649行推出命令调用了zk.close()方法图 36

图34

zookeeper客户端与服务端交互流程源码解析_第75张图片

图35

zookeeper客户端与服务端交互流程源码解析_第76张图片

图36

zookeeper客户端与服务端交互流程源码解析_第77张图片

 

 

zookeeper客户端与服务端交互流程源码解析_第78张图片

图37

zookeeper客户端与服务端交互流程源码解析_第79张图片

zookeeper客户端与服务端交互流程源码解析_第80张图片

图37 777行验证path ,传一个是否顺序节点标志。如果是顺序节点会在path上固定加上+1图38  ;779行创建一个根目录图40;781行构建一个请求头图41,设置一个类型为create 图42 ,构建一个createRequest , createResponse请求, 设置内容,标记,path, 权限,792行 submitRequest 图43,通过socket 发送请求到服务端,获取相应头,判断相应头是否有错误信息,有抛出异常,如果没有,拿到path返回。

图38

zookeeper客户端与服务端交互流程源码解析_第81张图片

图39

zookeeper客户端与服务端交互流程源码解析_第82张图片

zookeeper客户端与服务端交互流程源码解析_第83张图片

zookeeper客户端与服务端交互流程源码解析_第84张图片

 

图39验证path , 如果path的首字符不是/抛出异常,如果最后一位是/ 抛出异常,如果 -s 最后一位是/不会抛出异常,为什么吗,因为顺序节点默认+1了,最后一位就是1了,不会抛出异常。

图40

zookeeper客户端与服务端交互流程源码解析_第85张图片

加了一个根路径

图41

zookeeper客户端与服务端交互流程源码解析_第86张图片

 

图42

zookeeper客户端与服务端交互流程源码解析_第87张图片

图43

zookeeper客户端与服务端交互流程源码解析_第88张图片

图43  1407行 发送 queuePacket  一直阻塞等待直到 完成,才会唤醒,ReplyHeader有值才会返回。 

图44

zookeeper客户端与服务端交互流程源码解析_第89张图片

图44 把传进来的header,request,respolnse等等参数封装到yigePacket对象里,燃油放在一个outgoingQueue队列中。

 



服务端 接收请求和发送请求

图45

zookeeper客户端与服务端交互流程源码解析_第90张图片

图2

zookeeper客户端与服务端交互流程源码解析_第91张图片

判断是单机模式还是集群模式的标记是 有没有 图2的7行到10行。

图3

zookeeper客户端与服务端交互流程源码解析_第92张图片

图4

zookeeper客户端与服务端交互流程源码解析_第93张图片

图5

zookeeper客户端与服务端交互流程源码解析_第94张图片zookeeper客户端与服务端交互流程源码解析_第95张图片

 

图5  104 行把传过来的参数解 析为QuorumPeerConfig对象,并为这个对象的属性赋值,图6;113判断 servers是不是大于0,是则是集群模式,反之为单机模式。

图6

zookeeper客户端与服务端交互流程源码解析_第96张图片

图6 属于配置类 图7配置文件的类。

图7

zookeeper客户端与服务端交互流程源码解析_第97张图片

图8

zookeeper客户端与服务端交互流程源码解析_第98张图片

图8145行把配置文件通过流的形式转换为Properties文件,键值对的形式。152行开始解析图9

图9

zookeeper客户端与服务端交互流程源码解析_第99张图片

zookeeper客户端与服务端交互流程源码解析_第100张图片 

zookeeper客户端与服务端交互流程源码解析_第101张图片

zookeeper客户端与服务端交互流程源码解析_第102张图片

zookeeper客户端与服务端交互流程源码解析_第103张图片

zookeeper客户端与服务端交互流程源码解析_第104张图片

zookeeper客户端与服务端交互流程源码解析_第105张图片

zookeeper客户端与服务端交互流程源码解析_第106张图片

zookeeper客户端与服务端交互流程源码解析_第107张图片

zookeeper客户端与服务端交互流程源码解析_第108张图片

 zookeeper客户端与服务端交互流程源码解析_第109张图片

zookeeper客户端与服务端交互流程源码解析_第110张图片

zookeeper客户端与服务端交互流程源码解析_第111张图片

图9 229行 判断如果是observer ,设置一个observer标记,如果有这个标记则放在observers属性中其他放在servers 中。其他都是赋值操作。399行有一个过半校验的逻辑图10 ,可以发现过半校验并没有observer。

图10

zookeeper客户端与服务端交互流程源码解析_第112张图片

图10为过半机制。

 

你可能感兴趣的:(zookeeper)