一厂僧,Zookeeper客戶端的主要組件
Zookeeper客戶端主要由以下幾個核心部分組成:
1,Zookeeper實(shí)例:客戶端入口了牛。
通過調(diào)用Zookeeper構(gòu)造方法生成客戶端實(shí)例颜屠。
2,ClientWatchManager:客戶端Watcher管理器鹰祸。
3甫窟,HostProvider:客戶端地址列表管理器。
4蛙婴,ClientCnxn:客戶端核心線程粗井。內(nèi)部又包含2個線程,SendThread和EventThread街图。SendThread是一個IO線程浇衬,主要負(fù)責(zé)Zookeeper客戶端與服務(wù)端的網(wǎng)絡(luò)通信。EventThread是一個事件線程餐济,主要負(fù)責(zé)對服務(wù)端事件進(jìn)行處理耘擂。
二,Zookeeper客戶端的啟動流程
首先看一下Zookeeper構(gòu)造方法
Zookeeper(String connectString, int sessionTimeout, Watcher watcher, boolean canBeReadOnly)
初始化階段
1絮姆,設(shè)置默認(rèn)Watcher醉冤。
如果在Zookeeper的構(gòu)造方法中傳入一個Watcher對象的話,Zookeeper會將這個對象保存在ZKWatcherManager的defaultWatcher中滚朵,作為整個客戶端會話期間的默認(rèn)watcher冤灾。
2前域,設(shè)置Zookeeper服務(wù)器地址列表辕近。
對于傳入的服務(wù)器地址,客戶端會將其保存在服務(wù)器地址列表管理器HostProvider中匿垄。
3移宅,創(chuàng)建ClientCnxn。
Zookeeper客戶端首先會創(chuàng)建一個網(wǎng)絡(luò)連接器ClientCnxn椿疗,用來管理客戶端與服務(wù)端的網(wǎng)絡(luò)通信漏峰。
4,初始化SendThread和EventThread届榄。
SendThread是一個IO線程浅乔,主要負(fù)責(zé)Zookeeper客戶端與服務(wù)端的網(wǎng)絡(luò)通信。EventThread是一個事件線程,主要負(fù)責(zé)對服務(wù)端事件進(jìn)行處理靖苇。
會話創(chuàng)建階段
5席噩,啟動SendThread和EventThread。
SendThread首先會判斷當(dāng)前客戶端的狀態(tài)贤壁,進(jìn)行一系列清理工作悼枢,為客戶端發(fā)送會話創(chuàng)建請求做準(zhǔn)備。
6脾拆,獲取一個服務(wù)器地址馒索。
在開始創(chuàng)建TCP連接之前,SendThread首先需要獲取一個Zookeeper服務(wù)器的地址名船,這通常是從HostProvider中隨機(jī)獲取一個地址绰上,然后委托給ClientCnxnSocket去創(chuàng)建與Zookeeper服務(wù)端的TCP連接。
7渠驼,創(chuàng)建TCP連接渔期。
獲取到服務(wù)器地址后,ClientCnxnSocket負(fù)責(zé)和服務(wù)端創(chuàng)建一個TCP長連接渴邦。
8疯趟,構(gòu)造ConnectRequest請求。
SendThread根據(jù)當(dāng)前客戶端的實(shí)際設(shè)置谋梭,構(gòu)造一個ConnectRequest請求信峻,該請求代表了客戶端試圖與服務(wù)端創(chuàng)建一個會話。同時瓮床,Zookeeper客戶端還會進(jìn)一步將該請求包裝成網(wǎng)絡(luò)IO層的Packet對象盹舞,放入請求發(fā)送隊(duì)列outgoingQueue中。
9隘庄,發(fā)送請求踢步。
ClientCnxnSocket從outgoingQueue取出一個待發(fā)送的Packet對象,將其序列化成ByteBuffer后丑掺,向服務(wù)端進(jìn)行發(fā)送获印。
響應(yīng)處理階段
10,接收服務(wù)端響應(yīng)
ClientCnxnSocket接收到服務(wù)端的響應(yīng)后街州,會先判斷當(dāng)前的客戶端狀態(tài)是否是已初始化狀態(tài)兼丰。如果尚未完成初始化,那么就認(rèn)為該響應(yīng)一定是會話創(chuàng)建請求的響應(yīng)唆缴,直接交給readConnectResult方法來處理該響應(yīng)鳍征。
11,處理response
ClientCnxnSocket會對接收到的服務(wù)端響應(yīng)進(jìn)行反序列化面徽,得到ConnectResponse對象艳丛,并從中獲取到Zookeeper服務(wù)端分配的會話sessionId。
12,連接成功氮双。
連接成功后旺聚,一方面需要通知SendThread線程,進(jìn)一步對客戶端進(jìn)行會話參數(shù)的設(shè)置眶蕉,包括readTimeout和connectTimeout等砰粹,并更新客戶端狀態(tài)。另一方面造挽,需要通知地址管理器HostProvider當(dāng)前成功連接的服務(wù)器地址碱璃。
13,生成事件饭入,SyncConnected-None嵌器。
為了能夠讓上層應(yīng)用感知到會話的成功創(chuàng)建,SendThread會生成一個事件SyncConnected-None谐丢,代表客戶端與服務(wù)端創(chuàng)建會話成功爽航。并將該事件傳遞給EventThread。
14乾忱,查詢watcher
EventThread收到事件后讥珍,會從ClientWatchManager管理器查詢出對應(yīng)的watcher,針對SyncConnected-None事件窄瘟,找出步驟2中存儲的默認(rèn)的watcher衷佃,然后放到EventThread的waitingEvents隊(duì)列中。
15蹄葱,處理事件氏义。
EventThread不斷從waitingEvents隊(duì)列中取出待處理的watcher,然后直接調(diào)用該對象的process接口方法图云,以達(dá)到觸發(fā)watcher的目的惯悠。