ZooKeeper官方文檔之Java案例解讀
文檔原文連接:http://zookeeper.apache.org/doc/current/javaExample.html#sc_completeSourceCode
翻譯連接:http://www.dbjr.com.cn/article/236127.htm
需求理解
我們先回顧一下例子的需求,此客戶端有如下四個(gè)需求:
1、它接收如下參數(shù):
- ZooKeeper服務(wù)的地址
- 被監(jiān)控的znode的名稱
- 可執(zhí)行命令參數(shù)
2、它會(huì)取得znode上關(guān)聯(lián)的數(shù)據(jù),然后執(zhí)行命令
3、如果znode變化,客戶端重新拉取數(shù)據(jù),再次執(zhí)行命令
4、如果znode消失了,客戶端殺掉進(jìn)行的執(zhí)行命令
如果你已經(jīng)學(xué)習(xí)過或者了解過該例子文檔的內(nèi)容,你應(yīng)該知道該程序做的事情就是接受用戶輸入的系統(tǒng)命令,然后監(jiān)控zookeeper的znode,一旦znode存在,或者發(fā)生了變化,程序會(huì)把znode最新的數(shù)據(jù)存入文件,然后起一個(gè)線程執(zhí)行用戶的命令,同時(shí)還會(huì)起兩個(gè)線程輸出執(zhí)行結(jié)果及日志。
舉例類比
為了幫助理解,這里舉個(gè)現(xiàn)實(shí)的例子--警察抓壞人:
公安成立了一個(gè)行動(dòng)組準(zhǔn)備在嫌疑人住所進(jìn)行抓捕,警方人員安排如下:
- 組長(zhǎng)A負(fù)責(zé)總指揮
- 警察B負(fù)責(zé)監(jiān)控嫌疑人,并與組長(zhǎng)A聯(lián)絡(luò)
- 警察C,D,E,F(xiàn)埋伏在嫌疑人住所前后左右,準(zhǔn)備實(shí)施抓捕
整個(gè)抓捕過程是這樣的:
- 組長(zhǎng)A下達(dá)命令安排后,B,C各就各位(對(duì)象A做初始化工作)
- B開始監(jiān)控嫌疑人,一旦嫌疑人進(jìn)入警察布下的埋伏圈,則馬上通知組長(zhǎng)A(對(duì)象B為watcher,嫌疑人為被監(jiān)聽的znode。A注冊(cè)為B的listener,在B的監(jiān)聽回調(diào)中被觸發(fā))
- 組長(zhǎng)A得到通知后,馬上命令C、D、E、F執(zhí)行抓捕。(C,D,E是被A調(diào)用干活的線程)
理解了上線的例子,我們繼續(xù)對(duì)程序進(jìn)行講解。
Executor和DataMonitor
本例中有兩個(gè)主要類,職能如下:
Executor
,它是程序的入口。負(fù)責(zé)初始化zookeeper、DataMonitor,把自己注冊(cè)為DataMonitor的監(jiān)聽者,一旦DataMonitor監(jiān)聽到變化后,會(huì)通知它執(zhí)行業(yè)務(wù)操作。
他是例子中的組長(zhǎng)A,它有幾個(gè)內(nèi)部類是前面說的警員C、D、E、F,負(fù)責(zé)干活。
DataMonitor
,他負(fù)責(zé)監(jiān)控znode,發(fā)現(xiàn)znode變化后,通知listener執(zhí)行業(yè)務(wù)邏輯,同時(shí)再次監(jiān)控znode:
他是例子中的警察B,負(fù)責(zé)監(jiān)控犯人,并通知A。
通過以上講解,這兩個(gè)主要類所負(fù)責(zé)的工作應(yīng)該已經(jīng)可以充分的理解了。接下來我們針對(duì)這兩個(gè)類進(jìn)入更為詳細(xì)的講解。
內(nèi)部類和接口
Executor:
StreamWriter。繼承Thread,以多線程的形式負(fù)責(zé)把執(zhí)行的結(jié)果輸出。相當(dāng)于例子中的警察C、D、E、F
DataMonitor:
DataMonitorListener。DataMonitor一旦監(jiān)控到znode的變化,立即調(diào)用自己持有的listener(實(shí)現(xiàn)此接口的對(duì)象)的exists方法(通知它的監(jiān)聽者)。
繼承關(guān)系
Executor:
實(shí)現(xiàn)watcher:監(jiān)聽zookeeper連接的變化,實(shí)現(xiàn)process()方法,把事件傳遞給DataMonitor處理。
實(shí)現(xiàn)DataMonitor中定義的接口DataListener: 實(shí)現(xiàn)exists()方法,處理znode變化的具體邏輯。
實(shí)現(xiàn)runnable類: run()方法中阻塞主線程,讓程序轉(zhuǎn)為事件驅(qū)動(dòng)。
public class Executor implements Watcher, Runnable, DataMonitor.DataMonitorListener{}
DataMonitor:
實(shí)現(xiàn)watcher:
監(jiān)聽znode變化。實(shí)現(xiàn)process()方法,通過zk.exist()方法再次監(jiān)聽,再次設(shè)置自己為zookeeper.exist()的回調(diào)(實(shí)現(xiàn)不斷監(jiān)聽,事件驅(qū)動(dòng))。同時(shí)數(shù)據(jù)返回后,立即進(jìn)入下面的回調(diào)函數(shù)處理
實(shí)現(xiàn)StatCallback:
這是zookeeper.exist()操作回調(diào)對(duì)象。實(shí)現(xiàn)processResult()方法,調(diào)用DataMonitor持有的listener(也就是Excutor)的exists()方法執(zhí)行邏輯。
public class DataMonitor implements Watcher, StatCallback{}
引用關(guān)系
Executor:
- DataMonitor dm;
- ZooKeeper zk; //ZooKeeper的連接
- Process child; //真正執(zhí)行系統(tǒng)命令的子線程,相當(dāng)于警察C,D,E,F(xiàn)之一。
DataMonitor:
- ZooKeeper zk; //和Executor是同一個(gè)引用。Executor通過構(gòu)造函數(shù)傳入
- DataMonitorListener listener; //executor對(duì)象,Executor通過構(gòu)造函數(shù)傳入自己
圖解
Executor和DataMonitor的關(guān)系如下:
兩者通過Executor作為主入口,初始化DataMonitor和ZooKeeper對(duì)象后,阻塞主線程。轉(zhuǎn)為事件驅(qū)動(dòng)。即通過DataMonitor監(jiān)控znode上的事件來驅(qū)動(dòng)程序邏輯。
整個(gè)流程如下:
- Excutor把自己注冊(cè)為DataMonitor的監(jiān)聽
- DataMonitor實(shí)現(xiàn)watcher接口,并監(jiān)聽znode
- znode變化時(shí),觸發(fā)DataMonitor的監(jiān)聽回調(diào)
- 回調(diào)中通過ZooKeeper.exist() 再次監(jiān)聽znode
- 上一步exist的回調(diào)方法中,調(diào)用監(jiān)聽自己的Executor,執(zhí)行業(yè)務(wù)邏輯6
- Executor啟新的線程執(zhí)行命令
- Executor啟新的線程打印執(zhí)行命令的輸出
以上就是ZooKeeper官方文檔翻譯之Java例子解讀的詳細(xì)內(nèi)容,更多關(guān)于ZooKeeper文檔翻譯Java例子的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
jmeter如何自動(dòng)生成測(cè)試報(bào)告
這篇文章主要介紹了jmeter如何自動(dòng)生成測(cè)試報(bào)告,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-10-10Java Swing實(shí)現(xiàn)讓窗體居中顯示的方法示例
這篇文章主要介紹了Java Swing實(shí)現(xiàn)讓窗體居中顯示的方法,結(jié)合實(shí)例形式分析了swing使用setBounds方法控制窗口布局的相關(guān)操作技巧,需要的朋友可以參考下2017-11-11Spring MVC登錄注冊(cè)以及轉(zhuǎn)換json數(shù)據(jù)
本文主要介紹了Spring MVC登錄注冊(cè)以及轉(zhuǎn)換json數(shù)據(jù)的相關(guān)知識(shí)。具有很好的參考價(jià)值。下面跟著小編一起來看下吧2017-04-04詳解maven的setting配置文件中mirror和repository的區(qū)別
這篇文章主要介紹了詳解maven的setting配置文件中mirror和repository的區(qū)別,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-12-12Spring RabbitMQ死信機(jī)制原理實(shí)例詳解
這篇文章主要介紹了Spring RabbitMQ死信機(jī)制原理實(shí)例詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03解析Flink內(nèi)核原理與實(shí)現(xiàn)核心抽象
Flink API提供了開發(fā)的接口,此外,為了實(shí)現(xiàn)業(yè)務(wù)邏輯,還必須為開發(fā)者提供自定義業(yè)務(wù)邏輯的能力,下面為大家解析Flink內(nèi)核原理與實(shí)現(xiàn)核心抽象2021-08-08