JavaでZookeeperを操作するコードの例を詳しく説明します。
依存
同期とは、現在のスレッドがブロックされていて、サーバーがデータを返すのを待って、戻ってきたデータを受け取ってから続けて実行します。
非同期コールとは、結果(戻りデータ)の処理をコールバック関数に書き込み、現在スレッドが戻りを待っていないデータを続けて実行し、戻ってきたデータを受信すると自動的にコールバック関数を呼び出して処理することです。
データのコードを返した後の処理が、リターンデータやリターンデータの処理に依存しない場合、リターンデータの処理をコールバック関数として作成することができます。
ノードを作成
再帰的にサブノードを削除する方法が提供されていません。サブノードを有するznodeを削除するには、再帰的削除を自分で実現する必要があります。先にサブノードリストをGET_Children()に取得し、リストを巡回してサブノードを削除し、親ノードを削除しても良い。
サブノードリストを取得
watchは全部です。bootleanを書いてもいいです。モニターを追加してtrueを書いて、falseを書いてもいいです。Watchオブジェクトを書いてもいいです。newの一つのWatchのオブジェクトは傍受すると表しています。nullは傍受しないと表しています。
ノードデータの取得
ここには対応する非同期のコールバックが書かれていません。
acl権限を表示
watttcheevent.getType().equals(Event.Event Type.NodeData Chend)
wattchedEvent.getState().equals(Event.Keeper Sttes.SyncConneced)
getTypeはイベントタイプを取得し、getStateは接続状態を取得します。
以上のように、子孫ノードを再帰的に監視し、子孫ノードのデータ変更もNodeData Changedとし、子孫ノードの作成|削除もNodeCreated NodeDeletedとしてカウントされる。
モニターが設置されているzkCliだけが、ノードにイベントが発生した時にzkServerから通知があります。
watchはzkServerのメモリにのみ保存されています(zkはjdkに依存しています。jvmで実行しています。ヒープの中のsessionオブジェクト)。ハードディスクには耐久性がありません。つまり設定されたモニターは今回のセッション期間だけ有効です。zkCliは接続をオフしています。
待ち受けを削除
最後のパラメータ指定はzkServerに接続されていません。ローカル(zkCli)の傍受部分を削除するかどうか、true――除去します。false――除去しません。
例えばzkServerに接続されていません。ローカルモニターを削除して、10つの心拍内にzkServerを接続しました。zkServerの傍受部分はまだあります。イベントが発生した時はこのzkCliを通知しますが、zkCliローカルモニターはすでに除去されました。通知に対しては処理しません。
第一の方法は全体の傍受を除去し、傍受対象のウォッチに入る必要がない。
第二の方式の機能はより完全で、傍受のどの部分を削除するかを指定できますが、watchオブジェクトに入る必要があります。傍受を追加する時は変数を使ってwatchオブジェクトを保存します。
ここでは、JavaでZookeeperを操作する際のコード例についての詳細な文章を紹介します。Java操作Zookeeperの内容については、以前の文章を検索したり、下記の関連記事を引き続き閲覧したりしてください。これからもよろしくお願いします。
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.6.0</version>
</dependency>
zkServerに接続
// ,zkServer ip、port,
String connectStr = "192.168.1.9:2181";
//zookeeper zkCli
ZooKeeper zooKeeper = null;
try {
// 1。 , :1、 , final;2、 , try , final;3、 try , final
CountDownLatch countDownLatch = new CountDownLatch(1);
// ms,
zooKeeper = new ZooKeeper(connectStr, 5000, new Watcher() {
public void process(WatchedEvent watchedEvent) {
//
if (watchedEvent.getState().equals(Event.KeeperState.SyncConnected)) {
System.out.println(" ");
// -1
countDownLatch.countDown();
}
}
});
// , 0 。 , zk
countDownLatch.await();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
//... zk。 demo
//
try {
zooKeeper.close();
} catch (InterruptedException e) {
e.printStackTrace();
}
ノードが存在するかどうかを検出
//
//
Stat exists = null;
try {
// , Stat; , null。 watch
exists = zooKeeper.exists("/mall",false);
} catch (KeeperException | InterruptedException e) {
e.printStackTrace();
}
if (exists==null){
System.out.println(" ");
}
else {
System.out.println(" ");
}
//
zooKeeper.exists("/mall",false, new AsyncCallback.StatCallback() {
// path znode , ctx , znode
public void processResult(int i, String s, Object o, Stat stat) {
// , stat null
if (stat==null){
System.out.println(" ");
}
else{
System.out.println(" ");
}
}
// ctx,Object
},null);
操作後、サービス側は処理結果に戻り、void、nullに戻っても処理結果を計算します。同期とは、現在のスレッドがブロックされていて、サーバーがデータを返すのを待って、戻ってきたデータを受け取ってから続けて実行します。
非同期コールとは、結果(戻りデータ)の処理をコールバック関数に書き込み、現在スレッドが戻りを待っていないデータを続けて実行し、戻ってきたデータを受信すると自動的にコールバック関数を呼び出して処理することです。
データのコードを返した後の処理が、リターンデータやリターンデータの処理に依存しない場合、リターンデータの処理をコールバック関数として作成することができます。
ノードを作成
//
//
try {
// byte[], null; acl ZooDefs.Ids.OPEN_ACL_UNSAFE; ,P ,E ,S
zooKeeper.create("/mall", "abcd".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println(" /mall");
// ,
} catch (KeeperException | InterruptedException e) { System.out.println(" /mall , ");
e.printStackTrace();
}
//
zooKeeper.create("/mall", "abcd".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT, new AsyncCallback.Create2Callback(){
// path, ctx,
public void processResult(int i, String s, Object o, String s1, Stat stat) {
// , stat , , stat null
if (stat==null){
System.out.println(" /mall , ");
}
else {
System.out.println(" ");
}
}
//ctx
},null);
ノードを削除
//
//
try {
// ,-1
zooKeeper.delete("/mall1",-1);
System.out.println(" /mall");
} catch (InterruptedException | KeeperException e) {
System.out.println(" /mall ");
e.printStackTrace();
}
//
zooKeeper.delete("/mall2", -1, new AsyncCallback.VoidCallback() {
// path, ctx
public void processResult(int i, String s, Object o) {
}
//
//ctx
},null);
delete()は、サブノードがないznodeだけ削除します。このznodeにサブノードがあると、異常を投げます。再帰的にサブノードを削除する方法が提供されていません。サブノードを有するznodeを削除するには、再帰的削除を自分で実現する必要があります。先にサブノードリストをGET_Children()に取得し、リストを巡回してサブノードを削除し、親ノードを削除しても良い。
サブノードリストを取得
// ,List<String>, /mall/user,/mall/order, ["user"、"order"]
//
List<String> children = null;
try {
// watch
children = zooKeeper.getChildren("/mall", false);
} catch (KeeperException | InterruptedException e) {
e.printStackTrace();
}
System.out.println(" :" + children);
//
zooKeeper.getChildren("/mall", false, new AsyncCallback.ChildrenCallback() {
// :path、ctx、
public void processResult(int i, String s, Object o, List<String> list) {
System.out.println(" :" + list);
}
//ctx
}, null);
サブノードのみを取得し、孫ノードを取得しません。watchは全部です。bootleanを書いてもいいです。モニターを追加してtrueを書いて、falseを書いてもいいです。Watchオブジェクトを書いてもいいです。newの一つのWatchのオブジェクトは傍受すると表しています。nullは傍受しないと表しています。
ノードデータの取得
// , byte[]
//
byte[] data = null;
try {
// watch, stat
data = zooKeeper.getData("/mall", false, null);
} catch (KeeperException | InterruptedException e) {
e.printStackTrace();
}
// new String() data null, null NPE
if (data==null){
System.out.println(" ");
}
else{
System.out.println(" :"+new String(data));
}
//
zooKeeper.getData("/mall", false, new AsyncCallback.DataCallback() {
// :path、ctx、 、
public void processResult(int i, String s, Object o, byte[] bytes, Stat stat) {
// bytes null, , ; , bytes null
System.out.println(" :" + new String(bytes) );
}
//ctx
}, null);
ノードデータの変更を設定する
// |
//
try {
//
zooKeeper.setData("/mall", "1234".getBytes(), -1);
System.out.println(" ");
} catch (KeeperException | InterruptedException e) {
System.out.println(" ");
e.printStackTrace();
}
//
zooKeeper.setData("/mall", "1234".getBytes(), -1, new AsyncCallback.StatCallback() {
// path, ctx
public void processResult(int i, String s, Object o, Stat stat) {
}
// ctx
},null);
acl権限の設定
// acl
// , Id
ACL acl = new ACL(ZooDefs.Perms.ALL, new Id("auth", "chy:abcd"));
List<ACL> aclList = new ArrayList<>();
aclList.add(acl);
// List ACL ,
//List<ACL> aclList = Collections.singletonList(auth);
// , 。 ,
zooKeeper.addAuthInfo("digest","chy:abcd".getBytes());
// setAcl
try {
// List<ACL>,
zooKeeper.setACL("/mall", aclList, -1);
System.out.println(" ");
} catch (KeeperException | InterruptedException e) {
System.out.println(" ");
e.printStackTrace();
}
//
try {
zooKeeper.create("/mall","abcd".getBytes(),aclList,CreateMode.PERSISTENT);
System.out.println(" ");
} catch (KeeperException | InterruptedException e) {
e.printStackTrace();
}
権限を設定した後、zkServerに接続して操作する場合は、まずユーザーを検証する必要があります。ここには対応する非同期のコールバックが書かれていません。
acl権限を表示
// acl
// , , session
zooKeeper.addAuthInfo("digest","chy:abcd".getBytes());
//
try {
List<ACL> aclList = zooKeeper.getACL("/mall", null);
System.out.println("acl :"+aclList);
} catch (KeeperException | InterruptedException e) {
System.out.println(" acl ");
e.printStackTrace();
}
//
zooKeeper.getACL("/mall3", null, new AsyncCallback.ACLCallback() {
// :path、ctx、 List<ACL>、
public void processResult(int i, String s, Object o, List<ACL> list, Stat stat) {
// acl ,
System.out.println("acl :"+list);
}
//ctx
},null);
モニターを追加
//
try {
CountDownLatch countDownLatch = new CountDownLatch(1);
zooKeeper.getData("/mall", new Watcher() {
public void process(WatchedEvent watchedEvent) {
//watcher , process() ,
if (watchedEvent.getType().equals(Event.EventType.NodeDataChanged)){
System.out.println(" ");
// , ,
//countDownLatch.countDown();
}
}
}, null);
// watcher , , CountDownLatch
countDownLatch.await();
} catch (KeeperException | InterruptedException e) {
e.printStackTrace();
}
Zoo Keeper類のexists()、get Data()、get Children()方法はすべて傍受機能を追加しています。使い方は似ています。watttcheevent.getType().equals(Event.Event Type.NodeData Chend)
wattchedEvent.getState().equals(Event.Keeper Sttes.SyncConneced)
getTypeはイベントタイプを取得し、getStateは接続状態を取得します。
以上のように、子孫ノードを再帰的に監視し、子孫ノードのデータ変更もNodeData Changedとし、子孫ノードの作成|削除もNodeCreated NodeDeletedとしてカウントされる。
//
try {
CountDownLatch countDownLatch1 = new CountDownLatch(1);
zooKeeper.addWatch("/mall", new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
if (watchedEvent.getType().equals(Event.EventType.NodeDataChanged)){
System.out.println(" ");
// ,
//countDownLatch1.countDown();
}
}
// ,PERSISTENT ,PERSISTENT_RECURSIVE
}, AddWatchMode.PERSISTENT_RECURSIVE);
countDownLatch1.await();
} catch (KeeperException | InterruptedException e) {
e.printStackTrace();
}
count Down Latch 1.await()スレッドをブロックするには、新しいスレッドを起動してモニターしたほうがいいです。モニターが設置されているzkCliだけが、ノードにイベントが発生した時にzkServerから通知があります。
watchはzkServerのメモリにのみ保存されています(zkはjdkに依存しています。jvmで実行しています。ヒープの中のsessionオブジェクト)。ハードディスクには耐久性がありません。つまり設定されたモニターは今回のセッション期間だけ有効です。zkCliは接続をオフしています。
待ち受けを削除
//
try {
zooKeeper.addWatch("/mall",null,AddWatchMode.PERSISTENT);
System.out.println(" ");
} catch (KeeperException | InterruptedException e) {
e.printStackTrace();
}
上にモニターを追加する方法です。ウォッチウォッチパラメータは、bootleanタイプなら、falseに設定すれば傍受をオフできます。Watchタイプなら、nullで上書きする前に設定したモニターを設定できます。
//
try {
// Watcher, Watcher , null
// ,Any ,Data ,Children
// zkServe ,
zooKeeper.removeWatches("/mall",watcher, Watcher.WatcherType.Children,true);
} catch (InterruptedException | KeeperException e) {
e.printStackTrace();
}
傍受は2部構成で、一部はzkServerで、イベント発生時に対応するzkCliを通知します。一部はzkCliでzkServerの通知を受けた時にいくつかの処理を行います。最後のパラメータ指定はzkServerに接続されていません。ローカル(zkCli)の傍受部分を削除するかどうか、true――除去します。false――除去しません。
例えばzkServerに接続されていません。ローカルモニターを削除して、10つの心拍内にzkServerを接続しました。zkServerの傍受部分はまだあります。イベントが発生した時はこのzkCliを通知しますが、zkCliローカルモニターはすでに除去されました。通知に対しては処理しません。
第一の方法は全体の傍受を除去し、傍受対象のウォッチに入る必要がない。
第二の方式の機能はより完全で、傍受のどの部分を削除するかを指定できますが、watchオブジェクトに入る必要があります。傍受を追加する時は変数を使ってwatchオブジェクトを保存します。
ここでは、JavaでZookeeperを操作する際のコード例についての詳細な文章を紹介します。Java操作Zookeeperの内容については、以前の文章を検索したり、下記の関連記事を引き続き閲覧したりしてください。これからもよろしくお願いします。