官术网_书友最值得收藏!

6.4 ZooKeeper Java API操作

除了可以使用命令行方式對ZooKeeper進行操作外,ZooKeeper還提供了Java API操作接口。下面對ZooKeeper的常用Java API接口進行介紹。

6.4.1 創建Java工程

在編寫Java API之前,首先需要新建一個ZooKeeper項目。ZooKeeper項目的結構與普通的JavaSE項目一樣,只是依賴的jar包不同。

1. Maven項目

在Eclipse中新建一個Maven項目zk_demo(Maven項目的搭建此處不做過多講解),項目結構如圖6-5所示。

圖6-5 ZooKeeper Maven項目結構

然后在該項目的pom.xml文件中添加以下代碼,以引入ZooKeeper的Java API依賴包:

配置好pom.xml后,即可進行ZooKeeper Java API的編寫。

2. 普通JavaSE項目

若用戶不想使用Maven構建項目,也可以創建普通JavaSE項目。普通JavaSE項目依賴的ZooKeeper jar包主要有ZooKeeper核心包zookeeper-3.4.10.jar和三個日志包slf4j-log4j12-1.6.1.jar、slf4j-api-1.6.1.jar、log4j-1.2.16.jar。這4個jar包都可以在ZooKeeper安裝文件zookeeper-3.4.10.tar.gz中找到。其中核心包在安裝文件解壓后的根目錄,日志包在根目錄下的lib文件夾中。

一個ZooKeeper的普通JavaSE項目結構如圖6-6所示。

圖6-6 ZooKeeper普通JavaSE項目結構

6.4.2 創建節點

ZooKeeper創建節點不支持遞歸調用,即無法在父節點不存在的情況下創建一個子節點,如在/zk01節點不存在的情況下創建/zk01/ch01節點,并且如果一個節點已經存在,那么創建同名節點時,會拋出NodeExistsException異常。

下面創建一個節點/zk001,節點的元數據為“zk001_data”,步驟如下。

1. 編寫代碼

在新建的zk_demo項目中新建Java類CreatePath.java,然后在main()方法中寫入創建節點的代碼。完整代碼如下所示:

2. 程序解讀

? 新建一個ZooKeeper對象,傳入三個參數,解析如下:

  •  第一個參數為以逗號分隔的服務器連接字符串,格式為“IP地址:端口”或“主機名:端口”(使用主機名,需要在系統本地配置主機名IP映射),這里需要把所有的ZooKeeper服務器的地址都寫上,而不是只寫其中一臺。ZooKeeper客戶端對象將從連接串中挑選任意一個服務器進行連接,如果連接失敗,將嘗試連接另外一個服務器,直到建立連接。這樣的好處是能保證ZooKeeper服務的高可靠性,防止因為其中一臺服務器宕機而導致連接失敗。
  •  第二個參數為連接超時時間,這里是3秒。
  •  第三個參數為觀察者對象,連接成功后會調用觀察者對象中的回調方法,這里傳入null即可。

? 調用ZooKeeper對象的創建節點方法create(),返回創建的節點路徑,并需要傳入4個參數,解析如下:

  •  第一個參數為節點名稱。
  •  第二個參數為節點數據,需要轉成字節數組。
  •  第三個參數為權限控制,這里使用ZooKeeper自帶的完全開放權限Ids.OPEN_ACL_UNSAFE。
  •  第四個參數為創建模式CreateMode,它是一個枚舉類型,共有4個取值:PERSISTENT(持久節點,這種目錄節點存儲的數據不會丟失 ,即客戶端失去連接之后不會被自動刪除)、PERSISTENT_SEQUENTIAL(持久順序節點,這種節點在命名上會自動編號,根據當前已經存在的節點數自動加1)、EPHEMERAL(臨時節點,客戶端斷開連接時,這種節點會被自動刪除)、EPHEMERAL_SEQUENTIAL(臨時順序節點,客戶端斷開連接時,這種節點也會被自動刪除)。

create()方法的定義源碼如下:

CreateMode枚舉類的部分源碼如下:

3. 運行程序

直接在Eclipse中右擊運行該程序即可,觀察控制臺的輸出結果。若能成功輸出節點路徑,說明創建成功。

6.4.3 修改數據

使用ZooKeeper對象的setData()方法可以修改節點的元數據。例如,將節點/zk001的元數據修改為“zk001_data_new”,示例代碼如下:

setData()方法的三個參數解析如下:

  •  第一個參數為節點路徑。
  •  第二個參數為需要修改的元數據,并轉成字節數組。
  •  第三個參數為版本號,-1代表所有版本。

數據添加(或修改)成功后,會返回節點的狀態信息到Stat對象中,stat.getVersion()表示獲取該節點的版本號,默認新節點的版本號為0,每次對節點進行修改,版本號都會增加1。

setData()方法的定義源碼如下:

6.4.4 獲取數據

使用ZooKeeper對象的getData()方法可以獲得指定節點的元數據,示例代碼如下:

上述代碼獲取了節點/zk002的元數據,并將該節點的狀態信息放入了對象stat中,最后將元數據轉成字符串輸出到控制臺。如需查看節點狀態信息,可以從對象stat中進行輸出查看。

getData()方法的第二個參數傳入的是null,也可以指定一個觀察者對象Watcher,對節點數據的變化進行監聽,一旦有數據改變,就會觸發Watcher指定的回調方法。

對上述代碼進行改進,加入觀察者回調方法后,代碼如下:

上述代碼分析如下:

? process()方法是Watcher接口中的一個抽象方法,當ZooKeeper向客戶端發送一個Watcher 事件通知時,客戶端就會對相應的 process()方法進行回調,從而實現對事件的處理。

process()方法包含WatchedEvent類型的參數,WatchedEvent 包含了每一個事件的三個基本屬性:通知狀態(KeeperState)、事件類型(EventType)、節點路徑(Path),ZooKeeper 使用WatchedEvent 對象來封裝服務端事件并傳遞給 Watcher,從而方便回調方法process() 對服務端事件進行處理。

process()方法中通過代碼System.out.println(event.getType());輸出服務端的事件類型,此處控制臺的輸出結果為NodeDataChanged。從結果單詞的含義可知,節點數據被改變了。

? 為了能夠更好地驗證是否觸發了Watcher,不讓程序一次執行到底,從而加入了此部分代碼,讓程序一直停留在此處。

上述代碼實現了一次性監聽,當觸發Watcher后不會再次觸發,若需要持續進行監聽,可將上述代碼進行改進:定義一個Watcher對象,在process()方法中重新設置監聽,當ZooKeeper節點/zk002的狀態發生改變時將會觸發Watcher,輸出改變的事件類型。改進后的代碼如下:

getData()方法的定義源碼如下:

Watcher接口的源碼如下:

6.4.5 刪除節點

使用ZooKeeper對象的delete()方法可以對指定路徑節點進行刪除。例如,刪除節點/zk002,代碼如下:

上述代碼中,delete()方法的兩個參數解析如下:

  •  第一個參數為需要刪除的節點路徑。
  •  第二個參數為節點版本,-1代表刪除所有版本。

delete()方法的定義源碼如下:

主站蜘蛛池模板: 大荔县| 镇巴县| 河西区| 汉寿县| 额敏县| 屯门区| 韩城市| 舟曲县| 汉中市| 宜昌市| 青阳县| 四会市| 安丘市| 固安县| 荔浦县| 湛江市| 兴国县| 莫力| 漳浦县| 出国| 邻水| 宜丰县| 玉屏| 长汀县| 白朗县| 枞阳县| 天全县| 新闻| 南丰县| 河源市| 华阴市| 河西区| 桦南县| 河西区| 唐海县| 双鸭山市| 宜城市| 合江县| 康乐县| 万全县| 大化|