Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 启动后重试与Cassandra节点的连接_Java_Cassandra - Fatal编程技术网

Java 启动后重试与Cassandra节点的连接

Java 启动后重试与Cassandra节点的连接,java,cassandra,Java,Cassandra,我想使用Docker来启动我的应用程序和Cassandra数据库,我想使用Docker Compose来实现这一点。不幸的是,Cassandra的启动速度比我的应用程序慢得多,而且由于我的应用程序急切地初始化集群对象,我得到了以下异常: com.datastax.driver.core.exceptions.NoHostAvailableException: All host(s) tried for query failed (tried: cassandra/172.18.0.2:9042

我想使用Docker来启动我的应用程序和Cassandra数据库,我想使用Docker Compose来实现这一点。不幸的是,Cassandra的启动速度比我的应用程序慢得多,而且由于我的应用程序急切地初始化
集群
对象,我得到了以下异常:

com.datastax.driver.core.exceptions.NoHostAvailableException: All host(s) tried for query failed (tried: cassandra/172.18.0.2:9042 (com.datastax.driver.core.exceptions.TransportException: [cassandra/172.18.0.2:9042] Cannot connect))
    at com.datastax.driver.core.ControlConnection.reconnectInternal(ControlConnection.java:233)
    at com.datastax.driver.core.ControlConnection.connect(ControlConnection.java:79)
    at com.datastax.driver.core.Cluster$Manager.init(Cluster.java:1454)
    at com.datastax.driver.core.Cluster.init(Cluster.java:163)
    at com.datastax.driver.core.Cluster.connectAsync(Cluster.java:334)
    at com.datastax.driver.core.Cluster.connectAsync(Cluster.java:309)
    at com.datastax.driver.core.Cluster.connect(Cluster.java:251)

根据stacktrace和一些调试,Cassandra Java驱动程序似乎没有对初始启动应用重试策略。我觉得这有点奇怪。我是否有办法配置驱动程序,使其能够继续尝试连接到服务器,直到成功?

尝试增加连接超时,这是AWS等设备上有时会发生的一件事。我认为您正在查看错误日志的后期,在某个时候,它会告诉您由于超时或无法访问网络而无法连接,然后它会将节点标记为不可用

使用phantom,代码如下所示:

val Connector = ContactPoints(Seq(seedHost))
    .withClusterBuilder(_.withSocketOptions(
      new SocketOptions()
      .setReadTimeoutMillis(1500)
      .setConnectTimeoutMillis(20000)
    )).keySpace("bla")
资源链接:

您应该能够在NoHostAvailableException上编写一些try/catch逻辑,以便在等待5-10秒后重试连接。我建议您在特定时间段之后抛出异常之前只执行几次,您知道异常应该在该时间点开始

示例伪代码

连接makeCassandraConnection(int retryCount){
Exception lastException=新的IllegalStateException();
而(retryCount>0){
试一试{
return doConnectionStuff();
}捕获(无主机可用例外){
lastException=e;
重新计数--;
睡眠(时间单位为秒,toMillis(5));
}
}
抛出最后一个异常;
}

如果您不想更改客户端代码,并且客户端应用程序的docker容器因错误而停止,则可以在docker compose文件中为客户端应用程序使用以下属性

restart: unless-stopped
这将在客户端应用程序容器出现故障时重新启动它。docker-compose.yml文件示例:

version: '2'
services:
  cassandra:
    image: cassandra:3.5
    ports:
      - "9042:9042"
      - "9160:9160"
    environment:
      CASSANDRA_CLUSTER_NAME: demo
  app:
    image: your-app
    restart: unless-stopped

无法以这种方式配置Datastax驱动程序

<>如果这只是Docker的一个问题,你不想改变你的代码,你可以考虑使用一个简单的脚本来等待TCP端口在启动你的应用程序之前监听。是卡桑德拉的本地传输端口


其他选项是,但我个人只使用了wait for it,但发现它在docker中使用cassandra时非常有用。

如果您协调了许多docker,您应该使用depends-on标记进行docker compose

version: '2'
services:
  cassandra:
    image: cassandra:3.5
    ports:
      - "9042:9042"
      - "9160:9160"
    environment:
      CASSANDRA_CLUSTER_NAME: demo
  app:
    image: your-app
    restart: unless-stopped
    depends_on:
      - cassandra

你只有一个Cassandra节点?@SotiriosDelimanolis sure;我不需要更多的本地开发和测试,至少现在是这样。Cassandra还没有开始监听OP示例中的客户机。连接尝试将被拒绝,因为相应端口上没有侦听任何内容。超时不会改变这一点。Dependes-on标记只等待容器启动,Cassandra本身仍需要一些额外的时间来启动。是的,
Dependes-on
实际上不起作用,这是我尝试的第一件事。更重要的是,Dependes-on的条件已在docker 3中删除,所以你不能再等卡桑德拉恢复健康了,看来这就是我要做的。很奇怪,司机并不是自动这样做的。我可能会在他们的bug跟踪器中为这个特性创建一个记录单。如果多个线程试图调用这个方法呢?所有其他线程都必须等待,这是一个性能上的打击,对吗?实际上,我目前正是为了这个目的而使用的。除此之外,它还能够检查TCP端口的可用性。但是,很自然地,我希望驱动程序这样做。是的,这是一个可能的解决方案,但是如果应用程序重启不是免费的(例如,如果它有一些初始化要做),它就不起作用。目前,我的程序不需要进行任何复杂的初始化,但很有可能在将来需要类似的东西。