ZooKeeper非同步呼叫命令
在ZooKeeper中,所有的同步呼叫命令,都會有一個相應的非同步呼叫方法。非同步呼叫能在一個單獨執行緒中同時提交更多的命令,也能在一定程度上簡化程式碼實現。
1 非同步create方法
如建立zNode的命令create,同步方法的定義是
/** * @param path 建立節點的路徑 * @param data 建立節點的初始值 * @param acl 建立節點的ACL * @param createMode 建立節點使用永久還是臨時模式 * @return 建立節點的真實路徑 * @throws KeeperException 伺服器返回了非0的錯誤程式碼 * @throws KeeperException.InvalidACLException ACL非法或者為空 * @throws InterruptedException 事務被中斷 * @throws IllegalArgumentException 路徑非法 */ public String create(final String path, byte data[], List<ACL> acl, CreateMode createMode);
對應的非同步呼叫方法
/** * create方法的非同步呼叫方法 * @param path 建立節點的路徑 * @param data 建立節點的初始值 * @param acl 建立節點的ACL * @param createMode 建立節點使用永久還是臨時模式 * @param cb 包括回撥函式的物件 * @param ctx 上下文物件(非同步回撥時會傳遞給callback,方便出錯時重新呼叫) */ public void create(final String path, byte data[], List<ACL> acl, CreateMode createMode, StringCallback cb, Object ctx);
StringCallback的定義
interface StringCallback extends AsyncCallback { /** * 處理非同步呼叫的結果 * @param rc 呼叫的返回碼 * @param path 非同步呼叫時的路徑引數 * @param ctx 非同步呼叫時的上下文物件 * @param name 實際建立的節點名 * 成功時通常同path相同,除非建立的是sequential節點 */ public void processResult(int rc, String path, Object ctx, String name); }
非同步呼叫與同步呼叫的兩個主要區別:
- 非同步呼叫沒有返回值(void)
- 非同步呼叫不丟擲異常,異常情況都通過rc引數傳遞
2 部分rc程式碼定義
回撥函式的第一個引數 rc ,是呼叫的返回值。ZooKeeper在列舉org.apache.zookeeper.KeeperException.Code中做了定義。從原始碼中摘出一些我們可能會經常使用的Code
/** 一切安好 */ OK (Ok), /** 伺服器連線丟失 */ CONNECTIONLOSS (ConnectionLoss), /** 操作超時 */ OPERATIONTIMEOUT (OperationTimeout), /** 引數錯誤 */ BADARGUMENTS (BadArguments), /** 節點不存在 */ NONODE (NoNode), /** 臨時節點沒有子節點 */ NOCHILDRENFOREPHEMERALS (NoChildrenForEphemerals), /** 節點已經存在 */ NODEEXISTS (NodeExists), /** 節點有子節點 */ NOTEMPTY (NotEmpty), /** 會話超時 */ SESSIONEXPIRED (SessionExpired), /** 請求超時*/ REQUESTTIMEOUT (-122),
3 回撥函式的一般用法
下面是一個建立節點的簡單例子。注意,ctx引數傳遞的是data,這個引數會直接傳遞到callback函式中,這樣就可以直接重新呼叫create命令。
void createNode(String path, byte[] data) { zooKeeper.create(nodePath, data, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL, nodeCreateCallback, data); } AsyncCallback.StringCallback nodeCreateCallback = new AsyncCallback.StringCallback() { public void processResult(int rc, String path, Object ctx, String name) { switch (KeeperException.Code.get(rc)) { case OK: // 建立節點成功 break; case CONNECTIONLOSS: // 連線丟失,重新發布命令 createNode(path, ctx); return; default: // 其他異常,丟擲或記錄異常 KeeperException e = KeeperException.create(KeeperException.Code.get(rc), path); log.error("create node error", e); } } };
4 非同步回撥介面定義
ZooKeeper在org.apache.zookeeper.AsyncCallback中定義了幾個回撥介面
回撥介面 |
說明 |
適用的非同步命令 |
StatCallback |
用於獲取節點的狀態 |
void exists() void setData() |
DataCallback |
用於獲取節點的值和狀態 |
void getData() void getConfig() |
ACLCallback |
用於獲取節點的ACL資訊和狀態 |
void getACL() |
ChildrenCallback |
用於獲取節點的子節點列表 |
void getChildren() |
Children2Callback |
用於獲取節點的子節點列表和狀態 |
void getChildren() |
Create2Callback |
用於獲取節點的名稱和狀態 |
void create() |
StringCallback |
用於獲取節點的名稱 |
void create() |
VoidCallback |
不返回任何資訊 |
void delete() void sync() void removeWatches() void removeAllWatches() |
MultiCallback |
用於多命令請求的返回值 |
void multi() |
可以看到,有些非同步命令,可以選擇使用多個不同的Callback,見下表
非同步命令 |
可選的回撥介面 |
介面說明 |
void create() |
Create2Callback |
用於獲取節點的名稱和狀態 |
StringCallback |
用於獲取節點的名稱 |
|
void getChildren() |
ChildrenCallback |
用於獲取節點的子節點列表 |
Children2Callback |
用於獲取節點的子節點列表和狀態 |