ZooKeeper:第三方客戶端 ZKClient


 

 

 

ZkClient

       在使用ZooKeeper的Java客戶端時,經常需要處理幾個問題:重復注冊watcher、session失效重連、異常處理。

       要解決上述的幾個問題,可以自己解決,也可以采用第三方的java客戶端來完成。這里就介紹一種常用的客戶端zkclient,目前已經運用到了很多項目中,知名的有Dubbo、Kafka、Helix。

 

ZKClient的設計

 

 

 

 

ZkClient的組件說明

從上述結構上看,IZKConnection是一個ZkClient與ZooKeeper之間的一個適配器。在代碼里直接使用的是ZKClient,其實質還是委托了zookeeper來處理了。

       前面有一篇文章中,已經說了,使用ZooKeeper客戶端來注冊watcher有幾種方法:1、創建ZooKeeper對象時指定默認的Watcher,2、getData(),3、exists(),4、getchildren。其中getdata,exists注冊的是某個節點的事件處理器(watcher),getchildren注冊的是子節點的事件處理器(watcher)。而在ZKClient中,根據事件類型,分為了節點事件(數據事件)、子節點事件。對應的事件處理器則是IZKDataListener和IZKChildListener。另外加入了Session相關的事件和事件處理器。

       ZkEventThread是專門用來處理事件的線程。

重要處理流程說明

 

啟動ZKClient

在創建ZKClient對象時,就完成了到ZooKeeper服務器連接的建立。具體過程是這樣的:

      

 

1、  啟動時,指定好connection string,連接超時時間,序列化工具等。

2、  創建並啟動eventThread,用於接收事件,並調度事件監聽器Listener的執行。

3、  連接到zookeeper服務器,同時將ZKClient自身作為默認的Watcher。

 

為節點注冊Watcher

       ZooKeeper的三個方法:getData、getChildren、exists,ZKClient都提供了相應的代理方法。就拿exists來看:

 

可以看到,是否注冊watcher,由hasListeners(path)來決定的。

 

hasListeners就是看有沒有與該數據節點綁定的listener。

 

所以呢,默認情況下,都會自動的為指定的path注冊watcher,並且是默認的watcher(ZKClient)。怎么才能讓hasListeners判定值為true呢,也就是怎么才能為path綁定Listener呢?

ZKClient提供了訂閱功能:

 

 

一個新建的會話,只需要在取得響應的數據節點后,調用subscribteXxx就可以訂閱上相應的事件了。

 

 

ZooKeeper的變更操作

Zookeeper中提供的變更操作有:節點的創建、刪除,節點數據的修改。

 

創建操作,數據節點分為四種,ZKClient分別為他們提供了相應的代理:

 

刪除節點的操作:

 

 

修改節點數據的操作:

 

 

writeDataReturnStat():寫數據並返回數據的狀態。

updateDataSerialized():修改已序列化的數據。執行過程是:先讀取數據,然后使用DataUpdater對數據修改,最后調用writeData將修改后的數據發送給服務端。

 

客戶端處理變更

       前面已經知道,ZKClient是默認的Watcher,並且在為各個數據節點注冊的Watcher都是這個默認的Watcher。那么該是如何將各種事件通知給相應的Listener呢?

 

處理過程大致可以概括為下面的步驟:

1、判斷變更類型:變更類型分為State變更、ChildNode變更(創建子節點、刪除子節點、修改子節點數據)、NodeData變更(創建指定node,刪除節點,節點數據變更)。

 

2、取出與path關聯的Listeners,並為每一個Listener創建一個ZKEvent,將ZkEvent交給ZkEventThread處理。

3、ZkEventThread線程,拿到ZkEvent后,只需要調用ZkEvent的run方法進行處理。

 

從這里也可以知道,具體的怎么如何調用Listener,還要依賴於ZkEvent的run()實現了。

 

序列化處理

ZooKeeper中,會涉及到序列化、反序列化的操作有兩種:getData、setData。在ZKClient中,分別用readData、writeData來替代了。

對於readData:先調用zookeeper的getData,然后進行使用ZKSerializer進行反序列化工作。

對於writeData:先使用ZKSerializer將對象序列化后,再調用zookeeper的setData。

 

ZkClient如何解決使用ZooKeeper客戶端遇到的問題的呢?

 

Watcher自動重注冊:這個要是依賴於hasListeners()的判斷,來決定是否再次注冊。如果對此有不清晰的,可以看上面的流程處理的說明

       Session失效重連:如果發現會話過期,就先關閉已有連接,再重新建立連接。

       異常處理:對比ZooKeeper和ZKClient,就可以發現ZooKeeper的所有操作都是拋異常的,而ZKClient的所有操作,都不會拋異常的。在發生異常時,它或做日志,或返回空,或做相應的Listener調用。

 

 

相比於ZooKeeper官方客戶端,使用ZKClient時,只需要關注實際的Listener實現即可。所以這個客戶端,還是推薦大家使用的。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM