1.キュレーター入門
Apache Curatorは、カプセル化された高レベルAPIのセットを介してZooKeeperの操作を簡素化する、比較的完全なZooKeeperクライアントフレームワークです。公式文書を確認すると、キュレーターは主に次の3種類の問題を解決していることがわかります。
1.ZooKeeperクライアントとZooKeeperサーバー間の接続処理をカプセル化します。2。Fluent
スタイルの操作APIのセットを提供します。3。ZooKeeperの
さまざまなアプリケーションシナリオを提供します(分散ロックサービス、クラスターリーダーの選択、共有カウンター、キャッシュメカニズムなどのレシピ)。分散キューなど)抽象カプセル化
Curatorは主に、次の側面からzkの使用の複雑さを軽減します。
再試行メカニズム:プラグ可能な再試行メカニズムを提供し、すべての回復可能な例外をキャプチャするための再試行戦略を構成し、いくつかの内部標準再試行戦略(指数補正など)
接続も提供します。ステータス監視:キュレーターは初期化後、常にzk接続を監視します。接続ステータスが変更されると、それに応じて処理します
。zkクライアントインスタンス管理:キュレーターはzkクライアントをに送信します。サーバークラスターの接続が管理され、zkインスタンスは、zkクラスターへ
の接続の信頼性を確保するために必要に応じて再構築されます。さまざまな使用シナリオのサポート:キュレーターは、zkでサポートされているほとんどの使用シナリオを実装します(zk自体でサポートされていないシナリオでも)。これらの実装は、 zk、およびさまざまな極端なケースを検討します
2.プロジェクトでは、.pomファイルがキュレーターの依存関係を導入します
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>4.0.0</version>
</dependency>
3. Curatorクライアントを使用してzookeeperに接続し、zkノードの作成、変更、および削除を実現します。
public static void main(String[] args) throws Exception {
CuratorFramework cf = CuratorFrameworkFactory.builder()
.connectString("192.168.1.102:2181,192.168.1.102:2182,192.168.1.102:2183")//zk服务器地址
.sessionTimeoutMs(4000)// 超市时间
.retryPolicy(new ExponentialBackoffRetry(1000, 3))// 重试策略:初试时间为1s 重试10次
.namespace("curator-demo")//命名空间
.build();
cf.start();
System.out.println(States.CONNECTED);
System.out.println(cf.getState());
//创建持久化节点
cf.create().forPath("/che","123".getBytes());
//创建持久化有序节点
cf.create().withMode(CreateMode.PERSISTENT_SEQUENTIAL).forPath("/che_seq","che_seq data".getBytes());
//创建临时节点
cf.create().withMode(CreateMode.EPHEMERAL)
.forPath("/che/tmp1","tmp1data01".getBytes());
//创建临时有序节点
cf.create().withMode(CreateMode.EPHEMERAL_SEQUENTIAL) .forPath("/che/tmp2","tmp2data".getBytes());
cf.create().withProtection().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath("/che/tmp3","tmp3data".getBytes());
//测试检查某个节点是否存在
Stat stat1 = cf.checkExists().forPath("/che");
Stat stat2 = cf.checkExists().forPath("/che3");
System.out.println("'/che'是否存在: " + (stat1 != null ? true : false));
System.out.println("'/che3'是否存在: " + (stat2 != null ? true : false));
//获取某个节点的所有子节点
System.out.println(cf.getChildren().forPath("/"));
//获取某个节点数据
System.out.println(new String(cf.getData().forPath("/che")));
//设置某个节点数据
cf.setData().forPath("/che","new123".getBytes());
//创建测试节点
cf.create().orSetData().creatingParentContainersIfNeeded()
.forPath("/che/che005","che005data".getBytes());
cf.create().orSetData().creatingParentContainersIfNeeded()
.forPath("/che/che006","che006data".getBytes());
cf.create().forPath("/che/che007/che007001","che007001data".getBytes());
//删除该节点
cf.delete().forPath("/che/che005");
//级联删除子节点
cf.delete().guaranteed().deletingChildrenIfNeeded().forPath("/che/che007");
}
orSetData()メソッド:ノードが存在する場合、キュレーターはのsetData()メソッドに相当する、ノードの値を設定するために指定されたデータを使用する
creatingParentContainersIfNeeded()メソッド:指定されたノードの親ノードが存在しない場合、キュレーターは自動的にカスケードします親ノードの作成
warranted()メソッド:サーバーが正常に削除されても、クライアントが正常な削除プロンプトを受け取らない場合、キュレーターはバックグラウンドでノードの削除を試み続けます
。deletedChildrenIfNeeded()メソッド:削除するノードに子ノードがある場合、キュレーターはこのノードの子ノードをカスケード削除します
4.CuratorクライアントでのWatcherイベントの例
public class CuratorWatcherDemo {
public static void main(String[] args) throws Exception {
CuratorFramework cf = CuratorFrameworkFactory.builder()
.connectString("192.168.1.102:2181,192.168.1.102:2182,192.168.1.102:2183")//zk服务器地址
.sessionTimeoutMs(4000)// 超市时间
.retryPolicy(new ExponentialBackoffRetry(1000, 3))// 重试策略:初试时间为1s 重试10次
.namespace("curator-demo")//命名空间
.build();
cf.start();
System.out.println(States.CONNECTED);
System.out.println(cf.getState());
// PathChildCache 监听一个节点下子节点的创建、删除、修改事件
addListenerWithNodeChildCache(cf, "/che-test01");
// NodeCache 监听一个节点的修改和创建事件
addListenerWithNodeCache(cf, "/che-test01");
// TreeCache 监听所有节点的创建、删除、修改事件
addListenerWithTreeCache(cf, "/che-test01");
System.in.read();
}
/**
* PathChildCache 监听一个节点下子节点的创建、删除、修改事件
* @param cf
* @param path
* @throws Exception
*/
public static void addListenerWithNodeCache(CuratorFramework cf,String path) throws Exception {
@SuppressWarnings("resource")
final NodeCache nodeCache = new NodeCache(cf, path, false);
NodeCacheListener cacheListener = new NodeCacheListener() {
@Override
public void nodeChanged() throws Exception {
System.out.println("监听到节点事件:" + " - " + nodeCache.getCurrentData().getPath());
}
};
nodeCache.getListenable().addListener(cacheListener);
nodeCache.start();
}
/**
* NodeCache 监听一个节点的修改和创建事件
* @param cf
* @param path
* @throws Exception
*/
public static void addListenerWithNodeChildCache(CuratorFramework cf,String path) throws Exception {
@SuppressWarnings("resource")
final PathChildrenCache pathChildrenCache = new PathChildrenCache(cf, path, true);
PathChildrenCacheListener cacheListener = new PathChildrenCacheListener() {
@Override
public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception {
System.out.println("监听到子节点事件:" + event.getType());
}
};
pathChildrenCache.getListenable().addListener(cacheListener);
pathChildrenCache.start(PathChildrenCache.StartMode.NORMAL);
}
/**
* TreeCache 监听所有节点的创建、删除、修改事件
* @param cf
* @param path
* @throws Exception
*/
public static void addListenerWithTreeCache(CuratorFramework cf,String path) throws Exception {
@SuppressWarnings("resource")
final TreeCache treeCache = new TreeCache(cf, path);
TreeCacheListener cacheListener = new TreeCacheListener() {
@Override
public void childEvent(CuratorFramework client, TreeCacheEvent event) throws Exception {
System.out.println("监听到节点事件:" + event.getType() + " - " + event.getData().getPath());
}
};
treeCache.getListenable().addListener(cacheListener);
treeCache.start();
}
}