Ich benutze die Apache Curator-Bibliothek für die Durchführung von Führungswahlen auf dem Zookeeper. Ich habe meinen Anwendungscode auf verschiedenen Rechnern installiert und muss meinen Code nur von einem Rechner aus ausführen. Deshalb führe ich eine Führungswahl am Tierpfleger durch, damit ich prüfen kann, ob ich der Anführer bin, und dann diesen Code ausführen.Wie benutzt man LeaderElection Rezepte effizient mit Curator für Zookeeper?
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;
}
}
Und unten ist mein ZookeeperClient
Code
Unten ist meine LeaderElectionExecutor
Klasse, die dafür sorgt, ich pro Anwendung einen Kurator Instanz habe -
// 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;
}
}
Jetzt in meiner Anwendung, die ich benutze die Code wie folgt -
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
}
}
Problembeschreibung: -
In der Curator-Bibliothek - Aufruf von isLeader()
sofort nach dem Start der Verriegelung funktioniert nicht. Es braucht Zeit, bis der Anführer ausgewählt ist. Und nur aus diesem Grund habe ich einen Schlaf von 1 Minute in meinem LeaderElectionExecutor
Code hinzugefügt, der gut funktioniert, aber ich denke, ist nicht der richtige Weg, dies zu tun.
Gibt es einen besseren Weg, dies zu tun? Wenn ich das bedenke, muss ich prüfen, ob ich der Anführer bin, und dann diesen Code ausführen. Ich kann nicht alles in einer einzelnen Methode tun, also muss ich isLeader
Methode von den verschiedenen Klassen und von den Methoden anrufen, um zu überprüfen, ob ich der Führer bin, dann führe diesen Stück Code nur aus.
Ich bin mit Zookeeper 3.4.5 und Kurator 1.7.1 Version.