Драйвер Java Datastax не подключается, если отсутствует один хост

Если я не ошибаюсь, можно подключиться к кластеру Cassandra, зная хотя бы один из узлов, находящихся в кластере, а затем другие могут быть обнаружены.

Предположим, что у меня есть три узла (1, 2 и 3), и я подключаюсь к этим узлам следующим образом:

Cluster.builder().addContactPoints("1,2,3".split(",")).build();

Затем, если, например, node 3, и IP не может быть разрешен, эта строка кода будет вызывать IllegalArgumentException, как указано в документах:

@throws IllegalArgumentException if no IP address for at least one of {@code addresses} could be found

Почему кому-то нужно это поведение? Я хочу сказать, что если один из узлов не работает, я хочу, чтобы приложение могло работать, так как Cassandra все еще работает нормально.

Я проверил этот драйвер Java Cassandra: сколько контактных точек разумно? но это не отвечает на мой вопрос, поскольку он ничего не говорит о хостах, чем недоступен.

Как мне это сделать? Может быть, это изменилось в другой версии драйвера java? В настоящее время я использую cassandra-driver-core-3.0.3

Ответ 1

Это подтверждение только для того, чтобы убедиться, что все предоставленные хосты могут быть разрешены, он даже не проверяет, запущен ли сервер Cassandra на каждом хосте. Таким образом, в основном, убедитесь, что вы не делали никаких опечаток при предоставлении хостов, так как в действительности они не предполагают, что это может быть обычный прецедент, чтобы предоставить предоставленный хост, который не может быть разрешен.

Как обходной путь в вашем случае (хост удален из записей DNS), вы можете просто вызвать метод addContactPoint(String address) явно вместо используя addContactPoints(String... addresses) (который позади сцены просто вызывает addContactPoint(String address) для каждого предоставленного адреса) и самостоятельно управляет исключением.

Код может быть примерно таким:

Cluster.Builder builder = Cluster.builder();
// Boolean used to check if at least one host could be resolved
boolean found = false;
for (String address : "1,2,3".split(",")) {
    try {
        builder.addContactPoint(address);
        // One host could be resolved
        found = true;
    } catch (IllegalArgumentException e) {
        // This host could not be resolved so we log a message and keep going
        Log.log(
            Level.WARNING, 
            String.format("The host '%s' is unknown so it will be ignored", address)
        );
    }
}
if (!found) {
    // No host could be resolved so we throw an exception
    throw new IllegalStateException("All provided hosts are unknown");
}
Cluster cluster = builder.build();

FYI: Я только что создал билет, чтобы предложить усовершенствование драйвера Java https://datastax-oss.atlassian.net/browse/JAVA-1334.

Ответ 2

Как отметил Ник, он основан на разрешении DNS, а не на здоровье сервера Cassandra.

Если вы удаляете хосты из своей среды чаще, чем перекомпилируете свое приложение, то вам следует подумать о том, чтобы не выпекать ваши контактные точки в коде, а вместо этого кормить их другими средствами (переменная среды, служба REST, одна DNS-имя, которое всегда разрешает одно живое семя и т.д.).

Ответ 3

Документация существует только в отношении "разрешения" передаваемых точек контакта. Таким образом, конвертирование имен хостов в IP-адреса. Если вы указываете ip-адреса для начала, они не будут разрешены, просто проверены на достоверность. Если вы используете имена хостов, то каждая точка контакта должна быть разрешимой. Это не означает, что машина cassandra должна быть запущена, просто поиск DNS в имени хоста возвращает любой IP-адрес. Таким образом, случай, когда все будет нарушено, будет, если вы удалили запись DNS для одного из ваших контактных пунктов и перезапустили приложение.