zookeeperはどのように永久に傍受します

9675 ワード

コールバックの基礎知識
znodeは、このディレクトリノードに格納されているデータの変更、サブノードディレクトリの変化などを含めてモニタリングを設定するクライアントに通知することができ、この機能はzookeeperがアプリケーションにとって最も重要な特性であり、この特性によって実現できる機能は、構成の集中管理、クラスタ管理、分散ロックなどを含む.
//Zookeeperインスタンスを作成します.最初のパラメータはターゲットサーバアドレスとポートで、2番目のパラメータはSessionタイムアウト時間です.3つ目はノード変化時のコールバック方法ZooKeeper zk=new ZooKeeper("127.0.0.1:2181",500000,new Watcher()/トリガされたすべてのイベントpublic void process(WatchedEvent event){//dosomething}を監視する
     });APP 1のすべての構成を/APP 1 znodeの下に配置し、APP 1のすべてのマシンが起動すると/APP 1というノードを監視(zk.exist("/APP 1",true))し、コールバックメソッドWatcherを実現すると、zookeeper上/APP 1 znodeノードの下でデータが変化すると、各マシンは通知を受け取り、Watcherメソッドが実行され、アプリケーションはデータを取り外せばよい(zk.getData("/APP 1",false,null);
次の表に、書き込み操作とZK内部で発生したイベントの対応関係を示します.
 
event For “/path”
event For “/path/child”
create(“/path”)
EventType.NodeCreated
NA
delete(“/path”)
EventType.NodeDeleted
NA
setData(“/path”)
EventType.NodeDataChanged
NA
create(“/path/child”)
EventType.NodeChildrenChanged
EventType.NodeCreated
delete(“/path/child”)
EventType.NodeChildrenChanged
EventType.NodeDeleted
setData(“/path/child”)
NA
EventType.NodeDataChanged
一方、ZK内部の書き込みイベントとトリガされたwatcherの対応関係は以下の通りである.
event For “/path”
defaultWatcher
exists(“/path”)
getData(“/path”)
getChildren(“/path”)
EventType.None




EventType.NodeCreated
 


 
EventType.NodeDeleted
 
√(異常)

 
EventType.NodeDataChanged
 


 
EventType.NodeChildrenChanged
 
 
 

上記の2つのテーブルを総合すると、次の表に示すように、さまざまな書き込み操作がどのwatcherをトリガーできるかをまとめることができます.
 
“/path”
“/path/child”
 
exists
getData
getChildren
exists
getData
getChildren
create(“/path”)


 
 
 
 
delete(“/path”)



 
 
 
setData(“/path”)


 
 
 
 
create(“/path/child”)
 
 



 
delete(“/path/child”)
 
 




setData(“/path/child”)
 
 
 


 
セッションclose、authFail、invalidが発生すると、すべてのタイプのwatherがトリガーされます.
zkClientは便利な包装をしたほか、watcherの使用を少し強化しました.例えばsubscribeChildChangesは実際にexistsとgetChildrenを通じて2つのイベントに注目している.これによりcreate("/path")の場合、対応するpathにgetChildrenで登録されているlistenerも呼び出されます.またsubscribeDataChangesは実際にはexistsでイベントを登録しているだけです.上記の表から、更新の場合、existsとgetDataで登録されているwatcherはいずれもトリガーされるか、トリガーされないかがわかります.
getData,getChildren(),exists()の3つの方法は、パラメータ内のpathに対してwatcherを設定することができ、pathに対応するノードが変化すると、server側はwatcherを設定したclientに対して使い捨てのトリガ通知イベントを送信する.クライアントは、このトリガ通知イベントを受信した後、自分のビジネスロジックに従って対応する処理を行うことができる.
このwatcherの機能は使い捨てであることに注意し、watcher通知を引き続き取得したい場合は、イベントを処理した後、再びregisterします.
にしけんwatcherコールバックメカニズム
//Watcherインスタンス
Watcher wh = new Watcher() {
public void process(WatchedEvent event) {
System.out.println(「watcherインスタンスコールバック:パス」+event.getPath()+「タイプ:」
+ event.getType());
}
};
 
ZooKeeper zk = new ZooKeeper("10.15.82.166:3351", 500000, wh);
System.out.println("---------------------");
//ノードrootを作成します.データはmydataで、ACL権限制御を行わず、ノードは永続的です(つまりクライアントshutdownが消えても消えません)
zk.exists("/root", true);
zk.create("/root", "mydata".getBytes(), Ids.OPEN_ACL_UNSAFE,
CreateMode.PERSISTENT);
System.out.println("---------------------");
//rootの下にchildone znodeを作成します.データはchildoneで、ACL権限制御を行わず、ノードは永久的です.
zk.exists("/root/childone", true);
zk.create("/root/childone", "childone".getBytes(), Ids.OPEN_ACL_UNSAFE,
CreateMode.PERSISTENT);
System.out.println("---------------------");
//削除/root/childoneこのノード、2番目のパラメータはバージョン、-1の場合は直接削除し、バージョンを無視
zk.exists("/root/childone", true);
zk.delete("/root/childone", -1);
System.out.println("---------------------");
zk.exists("/root", true);
zk.delete("/root", -1);
System.out.println("---------------------");
//セッションを閉じる
zk.close();
---------------------
コールバックwatcherインスタンス:パスnullタイプ:None
コールバックwatcherインスタンス:パス/rootタイプ:NodeCreated
---------------------
コールバックwatcherインスタンス:パス/root/childoneタイプ:NodeCreated
---------------------
コールバックwatcherインスタンス:パス/root/childoneタイプ:NodeDeleted
---------------------
コールバックwatcherインスタンス:パス/rootタイプ:NodeDeleted
---------------------
さんえいきゅうコールバック
3種類のイベントがwatherをトリガーしてから機能しなくなり、いわゆる(一次作用)ですが、どのように永久に傍受しますか?これは私たちが更にプログラムの論理の上で制御する必要があって、ネット上でもっと良い方法があって、しかし、簡単な応用の中で、更にwatherの方法の中で更に傍受を設置することができて、この方法はとても愚かで、しかし、とても有効で、予想の効果を達成しました.
Watcher wh = new Watcher() {
        public void process(WatchedEvent event) {
            Log.AC_DEBUG("    watcher  :   " + event.getPath() + "   :"
                    + event.getType());

            if (event.getType() == EventType.None) {
                try { //
                        //   userauth       userpath
                    String auth_type = "digest";
                    zk.addAuthInfo(auth_type, userauth.getBytes());
                    zk.getData(userpath, null, null);
                } catch (Exception e) {
//                    e.printStackTrace();
                    Log.AC_ERROR("get node faild:userpath=" + userpath
                            + ",auth=" + userauth + " e:" + e.getMessage());
                    return;
                }
                Log.AC_INFO("userpath=" + userpath + " userauth=" + userauth);
            }

            try {

                switchinfo = getallswitch(); //   userpath             ,      

                //         
                Log.AC_DEBUG("lesson user=" + userpath + " node...");
                zk.exists(userpath, true); //           
                Log.AC_DEBUG("lesson user=" + AnonymousUSERpath + " node...");
                zk.exists(AnonymousUSERpath, true);

                //             
                if (zk.exists(userpath, false) != null) {
                    Log.AC_DEBUG("lesson user=" + userpath
                            + " 's swich node...");
                    List<String> swnodes = zk.getChildren(userpath, true); //
                    //   switch      
                    Iterator<String> it_sw = swnodes.iterator();
                    while (it_sw.hasNext()) {
                        String swpath = userpath + "/" + it_sw.next();
                        Log.AC_DEBUG("lesson user=" + swpath + " node...");
                        zk.exists(swpath, true);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                Log.AC_ERROR("lesson znode error:" + e.getMessage());
            }
        }
    };