1. 程式人生 > >Docker安裝&java-Zookeeper進行操作

Docker安裝&java-Zookeeper進行操作

Docker安裝Zookeeper
下載Zookeeper映象

docker pull zookeeper

啟動容器並新增對映

docker run --privileged=true -d --name zookeeper --publish 2181:2181 -d zookeeper:latest

檢視容器是否啟動

docker ps

 

idea提供了一個Zookeeper外掛,以供連線Zookeeper服務中心和檢視內容

開啟idea –》 Settings -》Plugins,搜尋Zoo進行下載安裝

 

配置Zookeeper的連線資訊

https://img-blog.csdn.net/20180702163121669?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI2NjQxNzgx/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70
ZooKeeper常用客戶端
zookeeper的常用客戶端有3種,分別是:zookeeper原生的、Apache Curator、開源的zkclient,下面分別對介紹它們:
zookeeper自帶的客戶端是官方提供的,比較底層、使用起來寫程式碼麻煩、不夠直接。
Apache Curator是Apache的開源專案,封裝了zookeeper自帶的客戶端,使用相對簡便,易於使用。
zkclient是另一個開源的ZooKeeper客戶端。

三個客戶端的Maven座標

 

<dependencies>
<!-- 原生zookeeper -->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.6</version>
</dependency>

<!--Apache Curator-->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.9
.0</version> </dependency> <!-- zkclient --> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>0.9</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> </dependencies>

 

三種ZooKeeper客戶端比較
由於Apache Curator是其中比較完美的ZooKeeper客戶端,所以主要介紹Curator的特性來進行比較!

Curator幾個組成部分

Client: 是ZooKeeper客戶端的一個替代品, 提供了一些底層處理和相關的工具方法
Framework: 用來簡化ZooKeeper高階功能的使用, 並增加了一些新的功能, 比如管理到ZooKeeper叢集的連線, 重試處理
Recipes: 實現了通用ZooKeeper的recipe, 該元件建立在Framework的基礎之上
Utilities:各種ZooKeeper的工具類
Errors: 異常處理, 連線, 恢復等
Extensions: recipe擴充套件
Curator主要解決了三類問題

封裝ZooKeeper client與ZooKeeper server之間的連線處理
提供了一套Fluent風格的操作API
提供ZooKeeper各種應用場景(recipe, 比如共享鎖服務, 叢集領導選舉機制)的抽象封裝
Curator列舉的ZooKeeper使用過程中的幾個問題

初始化連線的問題:
在client與server之間握手建立連線的過程中,如果握手失敗,執行所有的同步方法(比如create,getData等)將丟擲異常
自動恢復(failover)的問題: 當client與一臺server的連線丟失,並試圖去連線另外一臺server時,
client將回到初始連線模式
session過期的問題: 在極端情況下,出現ZooKeeper
session過期,客戶端需要自己去監聽該狀態並重新建立ZooKeeper例項
對可恢復異常的處理:當在server端建立一個有序ZNode,而在將節點名返回給客戶端時崩潰,此時client端丟擲可恢復的異常,使用者需要自己捕獲這些異常並進行重試
使用場景的問題:Zookeeper提供了一些標準的使用場景支援,但是ZooKeeper對這些功能的使用說明文件很少,而且很容易用錯.在一些極端場景下如何處理,zk並沒有給出詳細的文件說明.比如共享鎖服務,當伺服器端建立臨時順序節點成功,但是在客戶端接收到節點名之前掛掉了,如果不能很好的處理這種情況,將導致死鎖
Curator主要從以下幾個方面降低了zk使用的複雜性

重試機制:提供可插拔的重試機制, 它將給捕獲所有可恢復的異常配置一個重試策略,並且內部也提供了幾種標準的重試策略(比如指數補償)
連線狀態監控: Curator初始化之後會一直的對zk連線進行監聽, 一旦發現連線狀態發生變化, 將作出相應的處理
zk客戶端例項管理:Curator對zk客戶端到server叢集連線進行管理.並在需要的情況, 重建zk例項,保證與zk叢集的可靠連線
各種使用場景支援:Curator實現zk支援的大部分使用場景支援(甚至包括zk自身不支援的場景),這些實現都遵循了zk的最佳實踐,並考慮了各種極端情況
Curator聲稱的一些亮點

日誌工具
內部採用SLF4J 來輸出日誌 採用驅動器(driver)機制, 允許擴充套件和定製日誌和跟蹤處理,
提供了一個TracerDriver介面, 通過實現addTrace()和addCount()介面來整合使用者自己的跟蹤框架
和Curator相比, 另一個ZooKeeper客戶端——zkClient的不足之處
文件幾乎沒有異常處理弱爆了(簡單的丟擲RuntimeException) 重試處理太難用了 沒有提供各種使用場景的實現
對ZooKeeper自帶客戶端(ZooKeeper類)的”抱怨” 只是一個底層實現 要用需要自己寫大量的程式碼 很容易誤用
需要自己處理連線丟失, 重試等
測試程式碼:

public class CuratorTest {
public static void main(String[] args) throws Exception{
CuratorFramework client = CuratorFrameworkFactory.newClient("192.168.0.183:2181", new RetryNTimes(10, 5000));
client.start();// 連線
// 獲取子節點,順便監控子節點
List<String> children = client.getChildren().usingWatcher(new CuratorWatcher() {
public void process(WatchedEvent event) throws Exception
{
System.out.println("監控: " + event);
}
}).forPath("/");
System.out.println(children);
// 建立節點
String result = client.create().withMode(CreateMode.PERSISTENT).withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE).forPath("/test", "Data".getBytes());
System.out.println(result);
// 設定節點資料
client.setData().forPath("/test", "111".getBytes());
client.setData().forPath("/test", "222".getBytes());
// 刪除節點
//System.out.println(client.checkExists().forPath("/test"));
/*client.delete().withVersion(-1).forPath("/test");
System.out.println(client.checkExists().forPath("/test"));*/
client.close();
System.out.println("OK!");
}
}

 


ZooKeeper自帶客戶端(原生zookeeper)
ZooKeeper自帶客戶端的主要類是ZooKeeper類,ZooKeeper類物件除了需要ZooKeeper服務端連線字串(IP地址:埠),還必須提供一個Watcher物件。Watcher是一個介面,當伺服器節點花發生變化就會以事件的形式通知Watcher物件。所以Watcher常用來監聽節點,當節點發生變化時客戶端就會知道。\

ZooKeeper類還有對節點進行增刪改的操作方法,主要方法如下:

create:用於建立節點,可以指定節點路徑、節點資料、節點的訪問許可權、節點型別
delete:刪除節點,每個節點都有一個版本,刪除時可指定刪除的版本,類似樂觀鎖。設定-1,則就直接刪除節點。
exists:節點存不存在,若存在返回節點Stat資訊,否則返回null
getChildren:獲取子節點
getData/setData:獲取節點資料
getACL/setACL:獲取節點訪問許可權列表,每個節點都可以設定訪問許可權,指定只有特定的客戶端才能訪問和操作節點。

public class ZookpeerTest {
public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
ZooKeeper zk = new ZooKeeper("192.168.0.183:2181", 3000, new Watcher() {
public void process(WatchedEvent watchedEvent) {
System.out.println(watchedEvent.toString());
}
});
System.out.println("OK!");
// 建立一個目錄節點
/**
* CreateMode:
* PERSISTENT (持續的,相對於EPHEMERAL,不會隨著client的斷開而消失)
* PERSISTENT_SEQUENTIAL(持久的且帶順序的)
* EPHEMERAL (短暫的,生命週期依賴於client session)
* EPHEMERAL_SEQUENTIAL (短暫的,帶順序的)
*/
zk.create("/country", "China".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
// 建立一個子目錄節點
zk.create("/country/city", "China/Hangzhou".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println(new String(zk.getData("/country", false, null)));
// 取出子目錄節點列表
System.out.println(zk.getChildren("/country", true));
// 建立另外一個子目錄節點
zk.create("/country/view", "China/WestLake".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println(zk.getChildren("/country", true));
// 修改子目錄節點資料
zk.setData("/country/city", "China/Shanghai".getBytes(), -1);
byte[] datas = zk.getData("/country/city", true, null);
String str = new String(datas, "utf-8");
System.out.println(str);
// 刪除整個子目錄 -1代表version版本號,-1是刪除所有版本
// zk.delete("/path01/path01", -1);
// zk.delete("/path01/path02", -1);
// zk.delete("/path01", -1);
// System.out.println(str);
Thread.sleep(15000);
zk.close();
System.out.println("OK");
}
}

 

 

 


節點型別說明:
節點型別有4種:“PERSISTENT、PERSISTENT_SEQUENTIAL、EPHEMERAL、EPHEMERAL_SEQUENTIAL”其中“EPHEMERAL、EPHEMERAL_SEQUENTIAL”兩種是客戶端斷開連線(Session無效時)節點會被自動刪除;“PERSISTENT_SEQUENTIAL、EPHEMERAL_SEQUENTIAL”兩種是節點名字尾是一個自動增長序號。

節點訪問許可權說明:
節點訪問許可權由List確定,但是有幾個便捷的靜態屬性可以選擇:
- Ids.CREATOR_ALL_ACL:只有建立節點的客戶端才有所有許可權\
- Ids.OPEN_ACL_UNSAFE:這是一個完全開放的許可權,所有客戶端都有許可權
- Ids.READ_ACL_UNSAFE:所有客戶端只有讀取的

zkclient :

 

public class Zkclient {
public static void main(String[] args) throws Exception{
ZkClient zkClient = new ZkClient("192.168.0.183:2181");//建立連線
zkClient.create("/root","mydata", CreateMode.PERSISTENT);//建立目錄並寫入資料
String data=zkClient.readData("/root");
System.out.println(data);
//zkClient.delete("/root");//刪除目錄
//zkClient.deleteRecursive("/root");//遞迴刪除節目錄
}
}

 

特別感謝資料來源:https://www.cnblogs.com/LiZhiW/p/4923693.html