Zookeeper でリーダーシップの選挙を行うために、Apache Curator ライブラリを使用しています。私は自分のアプリケーション コードをさまざまなマシンにデプロイしており、コードを 1 台のマシンからのみ実行する必要があるため、飼育係でリーダーシップの選挙を行って、自分がリーダーであるかどうかを確認してからこのコードを実行できるようにしています。
以下は、LeaderElectionExecutor
アプリケーションごとに 1 つの Curator インスタンスがあることを確認するクラスです。
public class LeaderElectionExecutor {
private ZookeeperClient zookClient;
private static final String LEADER_NODE = "/testleader";
private static class Holder {
static final LeaderElectionExecutor INSTANCE = new LeaderElectionExecutor();
}
public static LeaderElectionExecutor getInstance() {
return Holder.INSTANCE;
}
private LeaderElectionExecutor() {
try {
String hostname = Utils.getHostName();
String nodes = "host1:2181,host2:2181;
zookClient = new ZookeeperClient(nodes, LEADER_NODE, hostname);
zookClient.start();
// added sleep specifically for the leader to get selected
// since I cannot call isLeader method immediately after starting the latch
TimeUnit.MINUTES.sleep(1);
} catch (Exception ex) {
// logging error
System.exit(1);
}
}
public ZookeeperClient getZookClient() {
return zookClient;
}
}
そして以下は私のZookeeperClient
コードです -
// can this class be improved in any ways?
public class ZookeeperClient {
private CuratorFramework client;
private String latchPath;
private String id;
private LeaderLatch leaderLatch;
public ZookeeperClient(String connString, String latchPath, String id) {
client = CuratorFrameworkFactory.newClient(connString, new ExponentialBackoffRetry(1000, Integer.MAX_VALUE));
this.id = id;
this.latchPath = latchPath;
}
public void start() throws Exception {
client.start();
leaderLatch = new LeaderLatch(client, latchPath, id);
leaderLatch.start();
}
public boolean isLeader() {
return leaderLatch.hasLeadership();
}
public Participant currentLeader() throws Exception {
return leaderLatch.getLeader();
}
public void close() throws IOException {
leaderLatch.close();
client.close();
}
public CuratorFramework getClient() {
return client;
}
public String getLatchPath() {
return latchPath;
}
public String getId() {
return id;
}
public LeaderLatch getLeaderLatch() {
return leaderLatch;
}
}
今、私のアプリケーションでは、次のようなコードを使用しています -
public void method01() {
ZookeeperClient zookClient = LeaderElectionExecutor.getInstance().getZookClient();
if (zookClient.isLeader()) {
// do something
}
}
public void method02() {
ZookeeperClient zookClient = LeaderElectionExecutor.getInstance().getZookClient();
if (zookClient.isLeader()) {
// do something
}
}
問題文:-
Curator ライブラリ -isLeader()
ラッチを開始した直後の呼び出しは機能しません。リーダーが選ばれるまでには時間がかかります。この理由だけで、LeaderElectionExecutor
コードに 1 分間のスリープを追加しましたが、これは正常に動作しますが、これは正しい方法ではないと思います。
これを行うより良い方法はありますか?これを念頭に置いて、私がリーダーであるかどうかを確認してから、このコードを実行する方法が必要です。1 つのメソッドですべてを行うことはできないためisLeader
、さまざまなクラスおよびメソッドからメソッドを呼び出して、自分がリーダーであるかどうかを確認し、このコードのみを実行する必要があります。
Zookeeper 3.4.5 と Curator 1.7.1 バージョンを使用しています。