Zookeeper——開源客戶端ZkClient

ZooKeeper開源的客戶端有ZkClient和Curator。我們先來學習一下ZkClient。
ZkClient
ZkClient在Zookeeper原生API接口上進行了包裝,是一個更易用的ZooKeeper客戶端。同時,ZkClient在內部實現了Session超時重連、Watcher反覆註冊等功能,使得ZooKeeper客戶端的這些繁瑣的細節工作對開發人員透明。
首先,需要引入ZkClient的Maven依賴:

<dependency>
			<groupId>com.101tec</groupId>
			<artifactId>zkclient</artifactId>
			<version>0.10</version>
		</dependency>

創建會話
在ZkClient中,有如下7種構造方法:

public ZkClient(String serverstring)
public ZkClient(String zkServers, int connectionTimeout)
public ZkClient(String zkServers, int sessionTimeout, int connectionTimeout)
public ZkClient(String zkServers, int sessionTimeout, int connectionTimeout, ZkSerializer zkSerializer)
public ZkClient(final String zkServers, final int sessionTimeout, final int connectionTimeout, final ZkSerializer zkSerializer, final long operationRetryTimeout)
public ZkClient(IZkConnection connection)
public ZkClient(IZkConnection connection, int connectionTimeout)
public ZkClient(IZkConnection zkConnection, int connectionTimeout, ZkSerializer zkSerializer)public ZkClient(final IZkConnection zkConnection, final int connectionTimeout, final ZkSerializer zkSerializer, final long operationRetryTimeout)

ZkClient構造方法參數說明:

參數名 說明
zkServers 指ZooKeeper服務器列表,由英文狀態逗號分開的host:port字符串組成,每一個都代表一臺ZooKeeper機器,如,192.168.1.1:2181,192.168.1.2:2181,192.168.1.3:2181
sessionTimeout 會話超時時間,單位爲毫秒。默認是30000ms
connectionTimeout 連接創建超時時間,單位爲毫秒。此參數表明如果在這個時間段內還是無法和ZooKeeper建立連接,那麼就放棄連接,直接拋出異常。
connection IZkConnection接口的實現類
zkSerializer 自定義序列化器

我們知道ZooKeeper原生API創建會話的時候,是一個異步的過程。而ZkClient通過內部包裝,將這個異步的會話創建過程同步化了,這對於開發者的使用來說非常方便。
IZkConnection接口裏麪包含了添、刪、改、查等一系列接口的定義。ZkClient默認提供對IZkConnection接口的兩種實現,分別是ZkConnection和InMemoryConnection,前者是我們最常用的實現方式。通常開發人員不需要對IZkConnection進行改造,直接使用ZkConnection這個實現就可以完成絕大部分的業務需求。
我們之前提過,ZooKeeper的節點內容只支持字節數組(byte[])類型,也就是說,Zookeeper不負責爲節點內容進行序列化,開發人員需要自己使用序列化工具將節點內容進行序列化和反序列化。ZkClient中定義了ZkSerializer接口,允許用戶傳入一個序列化實現,如Hessian或Kryo,默認情況下,ZkClient使用Java自帶的序列化方式進行對象的序列化。
ZkClient和ZooKeeper原生構造方的最大區別,就是在ZkClient的構造方法中,不再提供傳入Watcher對象的參數了。那麼客戶端如何去監聽服務端的相關事件呢?ZkClient引入了大多數Java程序都使用過的Listener來實現Watcher註冊。

創建節點
ZkClient提供了以下一系列接口來創建節點:

String create(final String path, Object data, final CreateMode mode)
String create(final String path, Object data, final List<ACL> acl, final CreateMode mode)
void createEphemeral(final String path)
void createEphemeral(final String path, final List<ACL> acl)
void createEphemeral(final String path, final Object data)
void createEphemeral(final String path, final Object data, final List<ACL> acl)
void createPersistent(String path, Object data)
void createPersistent(String path, boolean createParents)
void createPersistent(String path, Object data, List<ACL> acl)
String createPersistentSequential(String path, Object data)
String createPersistentSequential(String path, Object data, List<ACL> acl)
String createEphemeralSequential(final String path, final Object data)
String createEphemeralSequential(final String path, final Object data, final List<ACL> acl)

ZkClient create API參數說明:

參數名 說明
path 指定數據節點的節點路徑,即API調用的目的是創建該節點
data 節點的初始數據內容,可以傳入null
mode 節點類型,是一個枚舉類型,通常有4種可選的節點類型
acl 節點的ACL策略
createParents 指定是否創建父節點
//創建節點
ZkClient zkClient = new ZkClient("47.96.164.224:2181", 5000);
zkClient.createPersistent("/zkclient/zkclient1/zkclient1-1", true);

設置createParents參數爲true,表明需要遞歸創建父節點。

刪除節點
在ZkClient中,可以通過以下API來刪除指定節點:

boolean delete(final String path)
boolean deleteRecursive(String path)
boolean delete(final String path, final int version)

ZkClient delete API參數說明:

參數名 說明
path 數據節點的完整節點路徑
version 節點的版本號
//遞歸刪除節點
zkClient.deleteRecursive("/zkclient");

讀取數據
getChildren
在ZkClient中,可以通過以下API來獲取指定節點的子節點列表:

List<String> getChildren(String path)

在獲取子節點列表這個接口上,可以通過如下API來進行註冊監聽:

public List<String> subscribeChildChanges(String path, IZkChildListener listener)

通過該API的調用,就完成了事件監聽的註冊。從API方法中,可以看出,註冊的是對子節點列表變更的監聽,也就是說,一旦子節點列表發生變更,ZooKeeper服務端就會向客戶端發出事件通知,由這個Listener來處理。如下是Listener接口的定義:

public interface IZkChildListener {

    /**
     * Called when the children of the given path changed.
     * 
     * @param parentPath
     *            The parent path
     * @param currentChilds
     *            The children or null if the root node (parent path) was deleted.
     * @throws Exception
     */
    public void handleChildChange(String parentPath, List<String> currentChilds) throws Exception;
}
事件類型 說明
新增子節點 指定節點nodeA新增子節點,此時在handleChildChange方法中,parentPath收到的是nodeA的全路徑,currentChilds是最新的子節點列表(相對路徑)
減少子節點 指定節點nodeA減少子節點。此時在handleChildChange方法中,parentPath收到的是nodeA的全路徑,currentChilds是最新的子節點列表(相對路徑),可能是null
刪除節點 指定節點nodeA被刪除。此時在handleChildChange方法中,parentPath收到的是nodeA的全路徑,currentChilds是null

如下示例:

zkClient.subscribeChildChanges("/zkclient", new IZkChildListener() {
			@Override
			public void handleChildChange(String parentPath, List<String> currentChilds) throws Exception {
				System.out.println("parentPath======"+parentPath+"===="+currentChilds);
				for(String currentChild : currentChilds) {
					System.out.println("currentChild=========="+currentChild);
				}
			}
		});
zkClient.delete("/zkclient/zkclient1");
TimeUnit.SECONDS.sleep(1);

getData
在ZkClient中,可以通過以下API來獲取指定節點的數據內容:

public <T extends Object> T readData(String path)
public <T extends Object> T readData(String path, boolean returnNullIfPathNotExists)
public <T extends Object> T readData(String path, Stat stat)

示例如:

zkClient.subscribeDataChanges("/zkclient", new IZkDataListener() {
			@Override
			public void handleDataDeleted(String dataPath) throws Exception {
				System.out.println("刪除節點:"+dataPath);
			}
			
			@Override
			public void handleDataChange(String dataPath, Object data) throws Exception {
				System.out.println("節點名稱:"+dataPath+",修改後的值:"+data);
			}
		});
zkClient.writeData("/zkclient", "hello");
TimeUnit.SECONDS.sleep(1);
boolean result = zkClient.deleteRecursive("/zkclient");
System.out.println("result====="+result);
TimeUnit.SECONDS.sleep(1);
Object obj = zkClient.readData("/zkclient/zkclient1");
System.out.println("obj===="+obj);
TimeUnit.SECONDS.sleep(1);

更新數據
在ZkClient中,可以通過以下API來更新指定節點的數據:

void writeData(String path, Object object)
void writeData(final String path, Object datat, final int expectedVersion)

ZkClient writeData API參數說明:

參數名 說明
path 數據節點的完整節點路徑
data 數據內容,可以是null
expectedVersion 預期的數據版本,可以使用這個數據版本來實現類似CAS的原子操作

通過調用這個接口,就可以對指定節點進行數據更新了。

檢測節點是否存在
在ZkClient中,可以通過以下API來檢測指定節點是否存在:

boolean exists(final String path)

通過調用這個接口,就可以檢測指定節點是否存在了。
———————————————————————————————————————————
阿里雲福利

阿里雲3月採購季:https://www.aliyun.com/acts/product-section-2019/new-users?userCode=litzwg4e
雲主機2折
https://promotion.aliyun.com/ntms/act/qwbk.html?userCode=litzwg4e

阿里雲自營建站,買一送一:https://www.aliyun.com/jianzhan/?userCode=litzwg4e
商標註冊服務:https://tm.aliyun.com/?userCode=litzwg4e

作者:uk8692
來源:CSDN
原文:https://blog.csdn.net/uk8692/article/details/88032432
版權聲明:本文爲博主原創文章,轉載請附上博文鏈接!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章