Zookeeper client源碼篇

Java版本的Api主要涉及到兩個包:org.apache.zookeeperorg.apache.zookeeper.data

其余的包要么是Zookeeper內部使用盖桥,要么是Zookeeper服務實現(xiàn)的一部分亚斋。Java Client主要使用ZooKeeper這個類劲适,這個類有兩個構造方法碾篡,主要區(qū)別在于可以選擇是否傳入會話id和password铡羡。Zookeeper支持跨進程的會話id恢復機制拭嫁。有時一個Java應用程序會把會話id和password放在穩(wěn)定存儲服務中,當程序重啟時可以用于恢復早期的會話浮入。當創(chuàng)建好一個Zookeeper對象以后龙优,會新建兩個線程,一個IO線程和一個event線程事秀。IO線程基于Java Nio實現(xiàn)陋率,所有的輸入輸入操作都是通過此線程來完成。而所有的事件回調通過even線程來完成秽晚。會話保持比如重連、發(fā)送心跳由IO線程來完成筒愚。同步方法的響應也在IO線程里處理赴蝇。異步方法回調和監(jiān)聽事件的響應都是通過event線程來完成的。有幾個需要注意的點:

異步方法執(zhí)行和監(jiān)聽事件回調將按照完成順序有序執(zhí)行巢掺。調用者可以對回調事件進行任何處理句伶,但是同一時間不會處理到其他回調。

回調不會阻塞IO線程或者同步調用的執(zhí)行陆淀。

同步調用可能不會按照正確的順序返回考余。舉個栗子:假設客戶端發(fā)起一個異步讀/a請求,并且啟動/a的監(jiān)聽器轧苫,當成功讀取數(shù)據(jù)并且執(zhí)行異步回調的時候楚堤,在執(zhí)行邏輯里又發(fā)起了一個同步去/a的請求(雖然這種做法不推薦,但是代碼邏輯是沒有問題的),當兩次讀操作之間身冬,如果/a數(shù)據(jù)發(fā)生了變化衅胀,客戶端在獲取到同步讀結果之前,會收到/a發(fā)生變化的通知酥筝,但是由于事件隊列被異步回調阻塞住了(客戶端同一時間不會處理其他回調)滚躯,導致在變更event被執(zhí)行之前,同步讀操作會獲取到/a變化后的值嘿歌。

最后掸掏,來看下客戶端關閉邏輯。一旦Zookeeper被關閉或者收到了比如會話過期宙帝、授權失敗等事件丧凤,則Zookeeper對象會失效。在結束時茄唐,兩個線程關閉息裸,此時不應該對zookeeper句柄再進行任何操作。


1沪编、new ZooKeeper(String connectString,int sessionTimeout, Watcher watcher)發(fā)生的主要動作:

2呼盆、zookeeper.exists(String path,boolean watch, StatCallback cb, Object ctx)添加監(jiān)聽器的主要邏輯:

看源碼需要具備的知識儲備:java NIO,可以參考https://ifeve.com/overview/

3、代碼分析

基本上所有操作入口都在org.apache.zookeeper.Zookeeper

重點看一下ClientCnxn:創(chuàng)建了SendThread和EventThread兩個線程蚁廓,用于處理I/O和event访圃,

然后我們看下start()方法,就是啟動線程

再看下sendTread的run()方法相嵌,state的默認值是NOT_CONNECTED腿时,所以肯定能進到while里,并且由于當前沒有連接饭宾,所以會進入到startConnect()方法里批糟。


看下startConnect()方法,首先創(chuàng)建一個socketChanel看铆,然后調用registerAndConnect()將通道和地址綁定徽鼎。

接著看下registerAndConnect,首先像selector注冊socket連接事件弹惦,然后和addr建立連接否淤,最后primeConnection創(chuàng)建會話

看一下連接信息的填充方法primeConnection:主要是往outgoingQueue里寫和服務端的交互指令。這里包括重新注冊監(jiān)聽器棠隐,權限校驗信息寫入石抡。最后通過enableReadWriteOnly打開讀寫開關

再回過頭來看sendTread的run()方法。socket連接建立助泽,并且填充好基本的數(shù)據(jù)以后啰扛,接下來就是和服務端的數(shù)據(jù)傳輸了嚎京,主要是doTransport方法,涉及到zookeeper通信協(xié)議侠讯,這里暫時不展開

再來看下數(shù)據(jù)操作挖藏,我們以create為例:主要封裝在submitRequest里,最終會將數(shù)據(jù)存在outgoingQueue里

最后看下事件監(jiān)聽的部分:

首先通過exists(znode,true,watcher,Object)來啟用服務端的監(jiān)聽機制厢漩。第一步先通過ExistsWatchRegistration將watcher和znode綁定膜眠,然后將查找指令放到outgoingQueue傳送給服務端。

然后SendThread的readResponse用于處理服務端返回溜嗜,里面會根據(jù)path和事件類型宵膨,將新的event入隊。

void readResponse(ByteBuffer incomingBuffer)throws IOException {

WatchedEventwe =new WatchedEvent(event);

if (LOG.isDebugEnabled()) {

LOG.debug("Got " + we +" for sessionid 0x"

? ? ? ? ? ? + Long.toHexString(sessionId));

}

eventThread.queueEvent( we );//最后會將事件

}

接下來EventThread里run方法炸宵,通過processEvent(event)來處理event

可以看到processEvent方法里辟躏,最終會根據(jù)事件類型決定是否調用watcher.process呢還是調用statCallback.processResult()。

上述主要分析了client和server端會話建立的過程土全,以及具體的通信邏輯捎琐,還有event回調機制。缺少的一部分是客戶端如何獲取到服務端觸發(fā)的事件裹匙,這個和通信協(xié)議有關瑞凑,放到后面單獨來看。

參考文章:http://www.reibang.com/p/06e859181cc0

參考文章:https://blog.csdn.net/quhongwei_zhanqiu/article/details/45825975

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末概页,一起剝皮案震驚了整個濱河市籽御,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌惰匙,老刑警劉巖技掏,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異项鬼,居然都是意外死亡哑梳,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進店門绘盟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鸠真,“玉大人,你說我怎么就攤上這事奥此。” “怎么了雁比?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵稚虎,是天一觀的道長。 經常有香客問我偎捎,道長蠢终,這世上最難降的妖魔是什么序攘? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮寻拂,結果婚禮上程奠,老公的妹妹穿的比我還像新娘。我一直安慰自己祭钉,他們只是感情好瞄沙,可當我...
    茶點故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著慌核,像睡著了一般距境。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上垮卓,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天垫桂,我揣著相機與錄音,去河邊找鬼粟按。 笑死诬滩,一個胖子當著我的面吹牛,可吹牛的內容都是我干的灭将。 我是一名探鬼主播疼鸟,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼宗侦!你這毒婦竟也來了愚臀?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤矾利,失蹤者是張志新(化名)和其女友劉穎姑裂,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體男旗,經...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡舶斧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了察皇。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片茴厉。...
    茶點故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖什荣,靈堂內的尸體忽然破棺而出矾缓,到底是詐尸還是另有隱情,我是刑警寧澤稻爬,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布嗜闻,位于F島的核電站,受9級特大地震影響桅锄,放射性物質發(fā)生泄漏琉雳。R本人自食惡果不足惜样眠,卻給世界環(huán)境...
    茶點故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望翠肘。 院中可真熱鬧檐束,春花似錦、人聲如沸束倍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽肌幽。三九已至晚碾,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間喂急,已是汗流浹背格嘁。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留廊移,地道東北人糕簿。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像狡孔,于是被迫代替她去往敵國和親懂诗。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,472評論 2 348

推薦閱讀更多精彩內容