Куратор Apache: время от времени лидер не выбирается

Я использую рецепт выбора лидера куратора 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");
}
  1. Создайте экземпляр 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 {

            }
        }
    }
}
  1. Когда экземпляр сервера отключается, закройте экземпляр LSAdapter (какое приложение использует) и закройте созданный клиент CuratorFramework.
CloseableUtils.closeQuietly(lsAdapter);
curatorFrameworkClient.close();

Проблема, с которой я сталкиваюсь, заключается в том, что иногда при перезапуске сервера лидер не избирается. Я проверил это, проследив журнал внутри функции takeLeadership(). У меня есть два экземпляра сервера tomcat с приведенным выше кодом, подключающиеся к одному и тому же кворуму zookeeper, и в большинстве случаев один из экземпляров становится лидером, но когда возникает эта проблема, оба они становятся последователями. Пожалуйста, предложите, что я делаю неправильно.


person Viniti    schedule 04.06.2020    source источник


Ответы (1)


Как я ответил на кураторской Jira, вы проглатываете прерванное исключение. Когда вы получаете InterruptedException, вы должны выйти из takeLeadership(). В вашем примере кода вы просто сбрасываете прерванное состояние и продолжаете цикл - это вызовет бесконечный цикл прерванных исключений, кстати. После вызова Thread.currentThread().interrupt(); вы должны выйти из цикла while.

person Randgalt    schedule 06.06.2020