美文网首页zookeeper
zookeeper - session建立(4)

zookeeper - session建立(4)

作者: 晴天哥_王志 | 来源:发表于2018-05-04 23:26 被阅读82次

    概述

        在讲解完zookeeper核心的选举部分的功能逻辑之后,另外一个我个人觉得需要理解的就是zookeeper的client-server之间的连接的建立过程,因为除了zookeeper各个节点之间的通信外,另外一大块就是zookeeper作为server端与client端的交互,包括之前的连接建立以及后续的各种操作命令入get/set等操作,这个博文专注于讲清楚前面部分的概念,后面部分的逻辑会有专门的一篇博文来阐述。

        当然由于现在对于zookeeper的访问已经有很多开源的实现,排在首位的应该就是Curator了(最早介绍这个东西给我的还是我在车来了的同事袁翔,感谢当初带我入门),大部分情况我们使用的都是它封装的高级API,但是其实如果我们只是使用它的高级API而没有细究底层,我们还是不知道client-server之间的交互细节的,所以为了能够更直观的知道细节,我就在网上找了一个demo,基于这个demo我们可以开始开始我们的分析了。

    zookeeper-api

    说明

        上面中我们看到的client通过new ZooKeeper的api创建了server的连接,然后开始的一系列操作,所以我们的源码分析也从这个地方开始。

    zookeeper-session连接

    Session建立 - client端

        通过demo我们看出来,client连接zookeeper的server端其实就是创建了zookeeper对象。

        创建zookeeper对象,核心的点是创建了ClientXnxn对象,该对象内部包含两个核心对象,分别是sendThread和eventThread。

        启动zookeeper对象,实际上是启动sendThread和eventThread。当然我们关注的是sendThread这部分的工作,基本上建立连接(session的建立)也就是它在玩转的。

        在sendThread当中我们需要处理各种连接事件,譬如注册OP_CONNECT/OP_WRITE/

    OP_READ等相关事件。

    session-client-1

    说明:

        Zookeeper当中主要是创建了ClientXnxn对象并进行启动,其中ClientCnxn对象内部主要对象是两个线程,分别是是sendThread和eventThread,其中sendThread负责连接server。

    session-client-2

    说明:

        很明显的创建两个线程的逻辑,一个是sendThread,一个是eventThread。我们关注sendThread的run部分逻辑。

    session-sendThread-1

    说明:

        sendThread关联的几个对象包括sessionId,outgoingQueue等。

        sendThread内部如果判断clientCnxnSocket没有建立连接,就会开始尝试建立连接。

        我们关注的应该就是建立连接的过程,关注startConnect部分逻辑。

    session-sendThread-2

    说明:

        继续跟进connect部分的逻辑

    session-sendThread-3

    说明:

        继续跟进registerAndConnect部分的逻辑

    session-sendThread-4

    说明:

        首先将socket注册到selector当中并关注OP_CONNECT动作,这样异步连接成功的过程中就可以捕捉到事件了。

        如果立即连接成功以后就直接进入后续处理了,关注一下primeConnection这个动作,在异步连接成功后也会执行这个函数的。

    session-sendThread-5

    说明:

        连接成功我们开始发送相关报文给server端,其中发送是通过放到outgoing队列中,有专门的发送线程负责发送。

        其实发送了两种报文,但是不知道前面的报文是什么东西,看着像各种watch。

        最后最重要的部分在于connectionPrimed部分操作,其实就是注册了OP_READ和OP_WRITE事件到selector当中了。

    session-sendThread-6

    说明:

        其实这个run逻辑是在sendThread当中执行的,我们真正关心的部分逻辑是在doTransport部分,里面其实是对异步连接成功的处理。

    session-sendThread-7

    说明:

        进入doTransport的逻辑我们看到了selector的执行部分,其中select返回的就是感兴趣的事件,我们在registerAndConnect逻辑当中注册了OP_CONNECT事件,所以假设异步连接成功了那么我们就再次进入了sendThread.primeConnection的逻辑。

        在处理OP_CONNECT事件逻辑,sendThread.primeConnection的逻辑其实就是在发送package报文。    

        在处理OP_READ和OP_WRITE的逻辑,进入的其实是doIO部分的逻辑。

    session-sendThread-8

    说明:

        处理读事件也是一件挺有意思的事情,基本上你会看到ByteBuffer的各种用法,这里读取的逻辑其实很简单,先读取4Byte的数据长度,然后再读取剩余的实际报文数据。

        incomingBuffer一开始读取的是报文长度,在readLnegth()内部其实就是读取实际数据,根据sock.read(incomingBuffer)获取报文的长度。

    session-sendThread-9

    说明:

        处理写事件,基本上就是发送报文,细节没仔细关注。

    Session建立 - server端

        server端其实就是接收client端的连接,接受连接部分的逻辑似乎有点绕,所以我默认就从server端已经接受了连接并开始处理报文的逻辑开始。

        通过整个逻辑的串联了解下server对报文请求的处理,其实整个处理过程类似pipeLine的过程,由PrepRequestProcessor、SyncRequestProcessor、FinalRequestProcessor三者进行的串联。

    session-server-1

    说明:

        开始进入处理connect请求部分的逻辑,入口函数已经很明显了。

    session-server-2

    说明:

        进入创建session部分的逻辑,注意在这里生成了cnxn对象,session密码,超时时间等。

    session-server-3

    说明:

        创建session其实一个异步过程,这了我们生成了一个Request对象,然后提交这个Request对象。

    session-server-4

    说明:

        首先我们通过PrepRequestProcessor操作进行第一波处理,processRequest操作其实把request提交到一个队列当中submittedRequests当中,具体的消费处理逻辑看下一个逻辑代码。

    session-server-5

    说明:

        没错,这里开始进行第一波处理了,看函数就是PrepRequestProcessor进行处理,具体处理逻辑往后继续看。

    session-server-6

    说明:

        其实这个地方我们基本上知道了zookeeper处理请求的核心逻辑代码,我们只是现在关心session的create事件而已。

    session-server-7

    说明:

        这里我们看到createSession部分的逻辑,继续关注pRequest2Txn逻辑。

    session-server-8

    说明:

        我们将进行下一步下一步处理,至于nextProcessor从哪里来的呢,可以看下一个截图。

    其实nextProcessor其实是syncProcessor。

    session-server-9

    说明:

        基本上可以看出来了,PrepRequestProcessor、SyncRequestProcessor、FinalRequestProcessor。

    session-server-10

    说明:

        只是把任务简单的提交了另外一个queue当中,也就是queuedRequests当中。

    session-server-11

    说明:

        take任务继续下一步处理,这个还在SyncRequestProcessor当中,我们关注其实是flush动作,继续看下图的代码。

    session-server-12

    说明:

        其实flush里面最后还是将任务提交到给FinalRequestProcessor进行处理。

    session-server-13

    说明:

        进入zks.processTxn的逻辑,这部分代码其实很多,所以只截取了其中一部分。

    session-server-14

    说明:

        把session加入到全局session当中。

    session-server-15

    说明:

        真正完成session初始的入口函数。

    session-server-16

    说明:

        一开始通过serverCnxnFactory.registerConnection将session注册到server端,将session创建的结果发送回client端。

    session-server-17

    说明:

        在server端维持新建的session对象,但是我暂时也不知道干嘛。我们在创建ServerCnxnFactory的过程中会生成server端负责accept连接,这部分到时候后面再继续补充。

    参考文献

    使用ZooKeeper Java API编程

    Zookeeper源码分析之二Session建立

    相关文章

      网友评论

      本文标题:zookeeper - session建立(4)

      本文链接:https://www.haomeiwen.com/subject/agicrftx.html