zookeeper學習心得二:同步與非同步
上一節中,我們看到很多操作zk節點的方式有同步和非同步兩種方式,那麼問題來了:
(1)兩種方式有什麼區別?
(2)哪種方式更好?應該用那種方式來寫程式碼?
(3)最好的方式有哪些其他方面的知識?
本節我們從這三個角度來分析這個問題,畢竟基礎得好才可以更好的學習更深的內容。
1、同步 OR 非同步
ZooKeeper提供的Java API.每一個方法有一個非同步呼叫版本。非同步呼叫和同步呼叫的區別之處:
(1)同步呼叫中,需要處理異常。
(2)非同步呼叫中已經把異常封裝為返回碼。 同時非同步呼叫會得到更好的效能。這裡要注意,一般來說非同步呼叫會在命令傳送到Zookeeper伺服器之前,就返回繼續執行之後的程式碼。
2、推薦使用非同步方法
- 推薦使用非同步方法訪問Zookeeper,除了可以簡化異常處理,提高效能外。還應為Watcher的處理是異常的。這樣在構建複雜邏輯時,程式碼會更統一些。
- 因為回撥函式裡會有返回的伺服器響應碼,通過響應碼我們可以瞭解操作有沒有成功,沒有成功可以通過呼叫方法來實現第二次嘗試,比如生成一個節點,將生成節點的操作放進一個類中,通過伺服器響應碼來判斷是否生成成功,如果沒有成功,則繼續呼叫該方法,直到成功為止。
3、非同步回撥函式型別
使用非同步方式建立介面只需要實現AsyncCallback.StringCallback()介面即可,同時AsyncCallbackH還包含了StatCallback、DataCallback、ACLCallback、ChildrenCallback、Children2Callback、StringCallback和VoidCallback七種不同的回撥介面,使用者可以在不同的非同步介面中實現不同的介面。
實現介面的型別中還必須要實現相應的public void processResult(int rc, String path, Object ctx, String name) 函式,可能不同的回撥函式有不同的欄位。
欄位解讀:
int rc:Result code,服務端響應碼,客戶端可以從這個響應碼中識別API呼叫的結果,常見響應碼如下:
(1)0(ok):介面呼叫成功。
(2)-4(ConnectionLoss):客戶端和服務端連線已斷開。
(3)-110(NodeExists):指定節點已存在。
(4)-112(SessionExpired):會話已過期。
通過Code.get(rc)方法可以將rc轉換成相應的英文識別符號,例如下面:
switch (Code.get(rc)) {
case CONNECTIONLOSS:
System.out.println("CONNECTIONLOSS");
break;
case OK:
System.out.println("OK");
System.out.println("--ctx--"+ctx+"--"+name+"--path--"+path);
break;
case NODEEXISTS:
System.out.println("NODEEXISTS");
break;
default:
System.out.println("DEFAULT");
break;
}
String path:介面呼叫時傳入的API的資料節點的節點路徑引數值
Object ctx:介面呼叫時傳入的API的ctx引數值
String name:節點的名稱
這裡我一直有一個疑問:zookeeper中回撥函式用來幹嘛?難道就是用來將這些資訊打印出來?因為processResult是沒有返回型別的,除非我在回撥函式裡直接定義幾個字屬性,然後將processResult方法中的一些內容存進這些屬性裡,利用這些屬性的get方法來返回結果,只有當結果正確了才繼續執行主程式下一步的操作,但是這樣是不是又是多餘的操作。以上只是我的猜測,猜測回撥函式在zookeeper中的用處。