Я использую рецепт выбора лидера куратора Apache: https://curator.apache.org/curator-recipes/leader-election.html в моем приложении.
Версия Zookeeper: 3.5.7 Куратор: 4.0.1
Ниже приведена последовательность шагов: 1. Всякий раз, когда мой экземпляр сервера tomcat встает, я создаю один экземпляр CuratorFramework (один экземпляр на сервер tomcat) и запускаю его:
CuratorFramework client = CuratorFrameworkFactory.newClient(connectionString, retryPolicy);
client.start();
if(!client.blockUntilConnected(10, TimeUnit.MINUTES)){
LOGGER.error("Zookeeper connection could not establish!");
throw new RuntimeException("Zookeeper connection could not establish");
}
- Создайте экземпляр LSAdapter и запустите его:
LSAdapter adapter = new LSAdapter(client, <some_metadata>);
adapter.start();
Ниже мой класс LSAdapter:
public class LSAdapter extends LeaderSelectorListenerAdapter implements Closeable {
//<Class instance variables defined>
public LSAdapter(CuratorFramework client, <some_metadata>) {
leaderSelector = new LeaderSelector(client, <path_to_be_used_for_leader_election>, this);
leaderSelector.autoRequeue();
}
public void start() throws IOException {
leaderSelector.start();
}
@Override
public void close() throws IOException {
leaderSelector.close();
}
@Override
public void takeLeadership(CuratorFramework client) throws Exception {
final int waitSeconds = (int) (5 * Math.random()) + 1;
LOGGER.info(name + " is now the leader. Waiting " + waitSeconds + " seconds...");
LOGGER.debug(name + " has been leader " + leaderCount.getAndIncrement() + " time(s) before.");
while (true) {
try {
Thread.sleep(TimeUnit.SECONDS.toMillis(waitSeconds));
//do leader tasks
} catch (InterruptedException e) {
LOGGER.error(name + " was interrupted.");
//cleanup
Thread.currentThread().interrupt();
} finally {
}
}
}
}
- Когда экземпляр сервера отключается, закройте экземпляр LSAdapter (какое приложение использует) и закройте созданный клиент CuratorFramework.
CloseableUtils.closeQuietly(lsAdapter);
curatorFrameworkClient.close();
Проблема, с которой я сталкиваюсь, заключается в том, что иногда при перезапуске сервера лидер не избирается. Я проверил это, проследив журнал внутри функции takeLeadership(). У меня есть два экземпляра сервера tomcat с приведенным выше кодом, подключающиеся к одному и тому же кворуму zookeeper, и в большинстве случаев один из экземпляров становится лидером, но когда возникает эта проблема, оба они становятся последователями. Пожалуйста, предложите, что я делаю неправильно.