1. 程式人生 > >ZooKeeper非同步呼叫命令

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);
}

非同步呼叫與同步呼叫的兩個主要區別:

  1. 非同步呼叫沒有返回值(void)
  2. 非同步呼叫不丟擲異常,異常情況都通過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

用於獲取節點的子節點列表和狀態