zookeeper - session建立(4)

概述

    在讲解完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建立

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,175评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,674评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,151评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,597评论 1 269
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,505评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,969评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,455评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,118评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,227评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,213评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,214评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,928评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,512评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,616评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,848评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,228评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,772评论 2 339

推荐阅读更多精彩内容