Apache Curator - исключение потери соединения Zookeeper, возможная утечка памяти

Я работал над процессом, который непрерывно контролирует распределенный атомный длинный счетчик. Он контролирует каждую минуту, используя следующий класс ZkClientметод getCounter, На самом деле, у меня есть несколько запущенных потоков, каждый из которых отслеживает другой счетчик (распределенный атомарный длинный), хранящийся в узлах Zookeeper. Каждый поток указывает путь счетчика через параметры getCounter метод.

public class TagserterZookeeperManager {

public enum ZkClient {
    COUNTER("10.11.18.25:2181");  // Integration URL

    private CuratorFramework client;
    private ZkClient(String servers) {
        Properties props = TagserterConfigs.ZOOKEEPER.getProperties();
        String zkFromConfig = props.getProperty("servers", "");
        if (zkFromConfig != null && !zkFromConfig.isEmpty()) {
            servers = zkFromConfig.trim();
        }
        ExponentialBackoffRetry exponentialBackoffRetry = new ExponentialBackoffRetry(1000, 3);
        client = CuratorFrameworkFactory.newClient(servers, exponentialBackoffRetry);
        client.start();
    }

    public CuratorFramework getClient() {
        return client;
    }
}

public static String buildPath(String ... node) {
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < node.length; i++) {
        if (node[i] != null && !node[i].isEmpty()) {
            sb.append("/");
            sb.append(node[i]);
        }
    }
    return sb.toString();
}

public static DistributedAtomicLong getCounter(String taskType, int hid, String jobId, String countType) {
    String path = buildPath(taskType, hid+"", jobId, countType);
    Builder builder = PromotedToLock.builder().lockPath(path + "/lock").retryPolicy(new ExponentialBackoffRetry(10, 10));
    DistributedAtomicLong count = new DistributedAtomicLong(ZkClient.COUNTER.getClient(), path, new RetryNTimes(5, 20), builder.build());
    return count;
}

}

Из потоков, вот как я вызываю этот метод:

    DistributedAtomicLong counterTotal = TagserterZookeeperManager
                        .getCounter("testTopic", hid, jobId, "test");

Теперь, кажется, после нескольких часов работы потоков, на одном этапе я начинаю получать следующее org.apache.zookeeper.KeeperException$ConnectionLossException исключение внутри getCounter метод, в котором он пытается прочитать количество:

org.apache.zookeeper.KeeperException $ ConnectionLossException: KeeperErrorCode = ConnectionLoss для /contentTaskProd в org.apache.zookeeper.KeeperException.create(KeeperException.java:99) в org.apache.zookeeper.KeeperException.create (в org.apache.zookeeper.ZooKeeper.exists(ZooKeeper.java:1045) в org.apache.zookeeper.ZooKeeper.exists(ZooKeeper.java:1073) в org.apache.curator.utils.ZKPaths.mkdirs(ZKPaths.j):215) в org.apache.curator.utils.EnsurePath$InitialHelper$1.call(EnsurePath.java:148) в org.apache.curator.RetryLoop.callWithRetry(RetryLoop.java:107) в org.apache.curator.utils.EnsurePath$InitialHelper.ensure(EnsurePath.java:141) в org.apache.curator.utils.EnsurePath.ensure(EnsurePath.java:99) в org.apache.curator.framework.recipes.atomic.DistributedAtomicValue.getCurrentValuetribute (.java:254) в org.apache.curator.framework.recipes.atomic.DistributedAtomicValue.get(DistributedAtomicValue.java:91) в org.apache.curator.framework.recipes.atomic.DistributedAtomicLong.get(DistributedAtomicLong.java:72) ...

Я продолжаю получать это исключение некоторое время, и у меня возникает ощущение, что оно вызывает некоторые утечки внутренней памяти, которые в конечном итоге вызывают ошибку OutOfMemory, и весь процесс выручает. Кто-нибудь знает, какова причина этого? Почему Zookeeper внезапно начал выдавать исключение потери соединения? После того, как процесс вышел из строя, я могу вручную подключиться к Zookeeper через другую небольшую консольную программу, которую я написал (также используя куратор), и все там хорошо выглядит.

1 ответ

Для того, чтобы контролировать узел в Zookeeper, используя curator Вы можете использовать NodeCache, это не решит ваших проблем с соединением.... но вместо того, чтобы опрашивать узел раз в минуту, вы можете получить push-событие при его изменении.

По моему опыту, NodeCache неплохо справляется с отключением и возобновлением соединений.

Другие вопросы по тегам