ZooKeeper 提供了分佈式數據的發佈/訂閱功能。服務器
- 在 ZooKeeper 中,引入了 Watcher 機制來實現這種分佈式的通知功能。
- ZooKeeper 容許客戶端向服務端註冊一個 Watcher 監聽,
- 當服務器的一些特定事件觸發了這個 Watcher,那麼就會向指定客戶端發送一個事件通知來實現分佈式的通知功能。

- Watcher 機制主要包括客戶端線程、客戶端 WatchManager 和 ZooKeeper 服務器三部分。
- - ZooKeeper :部署在遠程主機上的 ZooKeeper 集羣,固然,也多是單機的。
- Client :分佈在各處的 ZooKeeper 的 jar 包程序,被引用在各個獨立應用程序中。
- WatchManager :一個接口,用於管理各個監聽器,只有一個方法 materialize(),返回一個 Watcher 的 set。
在具體流程上(簡單講),分佈式
- 客戶端在向 ZooKeeper 服務器註冊 Watcher 的同時,會將 Watcher 對象存儲在客戶端的 WatchManager 中。
- 當ZooKeeper 服務器觸發 Watcher 事件後,會向客戶端發送通知,
- 客戶端線程從 WatchManager 的實現類中取出對應的 Watcher 對象來執行回調邏輯。
工做機制
- Watcher 機制,總的來講能夠分爲三個過程:客戶端註冊 Watcher、服務器處理 Watcher 和客戶端回調 Watcher,
- 其內部各組件之間的關係如圖:

- 在建立一個 ZooKeeper 客戶端對象實例時,能夠向構造方法中傳入一個默認的 Watcher:
- 這個 Watcher 將做爲整個 ZooKeeper會話期間的默認 Watcher,會一直被保存在客戶端 ZKWatchManager 的 defaultWatcher 中。
- ZooKeeper 客戶端也能夠經過 getData、exists 和 getChildren 三個接口來向 ZooKeeper 服務器註冊 Watcher
- 不管哪一種方式,註冊 Watcher 的工做原理都是一致的。
ZooKeeper 的 Watcher 具備如下幾個特性。spa
- 一次性
- 不管是服務端仍是客戶端,一旦一個 Watcher 被觸發,ZooKeeper 都會將其從相應的存儲中移除。
- 所以,在 Watcher 的使用上,須要反覆註冊。這樣的設計有效地減輕了服務端的壓力。
- 客戶端串行執行
- 客戶端 Watcher 回調的過程是一個串行同步的過程,這爲咱們保證了順序,
- 同時,須要注意的一點是,必定不能由於一個 Watcher 的處理邏輯影響了整個客戶端的 Watcher 回調,
- 因此,我以爲客戶端 Watcher 的實現類要另開一個線程進行處理業務邏輯,以便給其餘的 Watcher 調用讓出時間。
- 輕量級
- WatchedEvent 是最小通知單元
- 僅僅通知客戶端發生了事件,不會帶事件具體內容,具體內容須要客戶端再次請求獲取
- 客戶端向服務端傳遞的也不是watcher 對象,使用Boolean類型標記屬性,服務端保存當前鏈接的ServerCnxn
watcher 事件類型線程
