【问题标题】:Datastax Java Driver does not connect if one host is missing如果缺少一台主机,Datastax Java 驱动程序不会连接
【发布时间】:2017-02-05 06:25:02
【问题描述】:

如果我没记错的话,可以连接到 Cassandra 集群,知道集群中的至少一个节点,然后可以发现其他节点。

假设我有三个节点(1、2 和 3),我像这样连接到这些节点:

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

然后,例如,如果节点 3 出现故障,并且无法解析 IP,则这行代码将抛出 IllegalArgumentException,如文档中所述:

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

为什么会有人想要这种行为?我的意思是,如果其中一个节点出现故障,我希望应用程序能够运行,因为 Cassandra 仍然可以正常工作。

我已经检查了这个Cassandra Java driver: how many contact points is reasonable? 但这并不能回答我的问题,因为它没有说明主机无法访问。

我应该如何处理?也许这在另一个版本的 java 驱动程序中有所改变?我目前正在使用cassandra-driver-core-3.0.3

【问题讨论】:

    标签: java cassandra datastax


    【解决方案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();
    

    仅供参考:我刚刚创建了一张票,建议改进 Java 驱动程序https://datastax-oss.atlassian.net/browse/JAVA-1334

    【讨论】:

    • 这是一个很好的解决方法!另外,感谢您创建票证!
    【解决方案2】:

    正如尼克所说,它基于 DNS 解析,而不是 Cassandra 服务器的健康状况。

    如果您从环境中移除主机的次数多于重新编译应用程序的次数,那么您应该考虑不要将您的联系点烘焙到代码中,而是通过其他方式(环境变量、REST 服务、单个始终解析为一个活种子的 DNS 名称等)。

    【讨论】:

    • 我们的环境确实比我们的代码变化更频繁,我们有一个私有云,我们的虚拟机可以动态变化。您有一个观点,我们可以尝试从我们的最终实施解决方法,但我也认为这个验证可以修复,因为集群仍然可以在 Pablo 描述的状态下工作,但应用程序不会启动。
    • 如果您不想实施解决方法,我建议向 java 驱动程序 datastax-oss.atlassian.net/projects/JAVA/summary 提交问题。我认为只要求一个主机名可解析并丢弃任何没有警告的主机名的行为可能是合理的。无论如何,我认为您已经回答了您的问题。堆栈溢出赏金并不是真正用于获取代码更改,但我绝对建议提交补丁和票证,以便尽快发布修复程序。
    【解决方案3】:

    那里的文档只是关于“解析”传入的联系点。因此将主机名转换为 IP 地址。如果您指定 IP 地址开始,它们将不会被解析,只需检查其有效性。如果您使用主机名,则每个联系点都需要是可解析的。这并不意味着 cassandra 机器需要运行,只是主机名上的 DNS 查找会返回任何 IP 地址。因此,如果您删除了其中一个联系点的 DNS 条目并重新启动应用程序,事情就会中断。

    【讨论】:

    • 是的,我知道,我引用了。我正在寻找一种解决方案,如果无法访问节点,则代码可以工作。
    • 我是说它已经做到了。仅当指定的所有 个接触点均不可到达时,才会引发异常。如果联系点的一个子集无法访问,事情仍然可以工作。
    • 不,我认为你错了。文本清楚地说明了“至少一个”,这意味着如果没有找到 ONE 的 IP 地址,那么它会引发异常。我检查了代码,就像这样。还测试了将“asdasd”写为另外一个 ip 并且它崩溃了。
    • 您应该检查该短语是否显示“如果 no IP 地址 ...可以找到。”
    • 是的,文档消息只是令人困惑,我会看看是否可以更新。无论如何,这只是指传入的主机名是否可解析,不可访问。因此,即使 Cassandra 没有运行,传递有效的主机名或 ips 仍然可以正常工作。
    猜你喜欢
    • 2018-10-18
    • 2015-05-29
    • 2013-12-23
    • 2018-07-16
    • 2014-04-24
    • 2013-10-25
    • 2017-01-02
    • 2017-07-05
    • 2013-07-14
    相关资源
    最近更新 更多