【问题标题】:Error connecting ScyllaDB in Docker from Spring Boot app从 Spring Boot 应用程序连接 Docker 中的 ScyllaDB 时出错
【发布时间】:2022-07-20 12:40:20
【问题描述】:

我希望有人可以帮助我解决这个问题,因为我不是 docker 专家。

我有一个使用 ScyllaDB 的 Java Spring Boot 应用程序(我们称之为 my-app)。到目前为止,我一直在使用 Spring Boot 嵌入式 Apache Tomcat 构建运行应用程序,并且数据库在 Docker 中运行,没有任何问题。

这是 3 个 Scylla 节点的 docker-compose 文件:

version: \"3\"

services:

  scylla-node1:
    container_name: scylla-node1
    image: scylladb/scylla:4.5.0
    restart: always
    command: --seeds=scylla-node1,scylla-node2 --smp 1 --memory 750M --overprovisioned 1 --api-address 0.0.0.0
    ports:
      - 9042:9042
    volumes:
      - \"./scylla/scylla.yaml:/etc/scylla/scylla.yaml\"
      - \"./scylla/cassandra-rackdc.properties.dc1:/etc/scylla/cassandra-rackdc.properties\"
    networks:
      - scylla-network

  scylla-node2:
    container_name: scylla-node2
    image: scylladb/scylla:4.5.0
    restart: always
    command: --seeds=scylla-node1,scylla-node2 --smp 1 --memory 750M --overprovisioned 1 --api-address 0.0.0.0
    ports:
      - 9043:9042
    volumes:
      - \"./scylla/scylla.yaml:/etc/scylla/scylla.yaml\"
      - \"./scylla/cassandra-rackdc.properties.dc1:/etc/scylla/cassandra-rackdc.properties\"
    networks:
      - scylla-network

  scylla-node3:
    container_name: scylla-node3
    image: scylladb/scylla:4.5.0
    restart: always
    command: --seeds=scylla-node1,scylla-node2 --smp 1 --memory 750M --overprovisioned 1 --api-address 0.0.0.0
    ports:
      - 9044:9042
    volumes:
      - \"./scylla/scylla.yaml:/etc/scylla/scylla.yaml\"
      - \"./scylla/cassandra-rackdc.properties.dc1:/etc/scylla/cassandra-rackdc.properties\"
    networks:
      - scylla-network

使用节点工具,我可以看到数据库很好:

Datacenter: DC1
--  Address     Load       Tokens       Owns    Host ID                               Rack
UN  172.27.0.3  202.92 KB  256          ?       4e2690ec-393b-426d-8956-fb775ab5b3f9  Rack1
UN  172.27.0.2  99.5 KB    256          ?       ae6a0b9f-d0e7-4740-8ebe-0ce1d2e9ea7e  Rack1
UN  172.27.0.4  202.68 KB  256          ?       7a4b39bf-f38a-41ab-be33-c11a4e4e352c  Rack1

在应用程序中,我使用的 Java 驱动程序是用于 Apache Cassandra 的 DataStax Java 驱动程序 3.11.2.0。我与数据库的连接方式如下:

@Bean
    public Cluster cluster() {
        Cluster cluster = Cluster.builder().addContactPointsWithPorts(
                        new InetSocketAddress(\"127.0.0.1\", 9042),
                        new InetSocketAddress(\"127.0.0.1\", 9043),
                        new InetSocketAddress(\"127.0.0.1\", 9044))
                .build();
        return cluster;
    }

    @Bean
    public Session session(Cluster cluster, @Value(\"${scylla.keyspace}\") String keyspace) throws IOException {
        final Session session = cluster.connect();
        setupKeyspace(session, keyspace);
        return session;
    }

使用 tomcat 服务器运行应用程序时,我在启动时收到很多连接错误:

2022-07-19 22:42:38.424  WARN 28228 --- [r1-nio-worker-3] com.datastax.driver.core.Connection      : Error creating netty channel to /172.27.0.4:9042

然而,在少量的日志错误垃圾邮件之后,应用程序最终连接并完全可用。不过,我确实必须等待节点工具执行并确认所有节点都已启动。

2022-07-19 23:25:12.324  INFO 25652 --- [  restartedMain] c.d.d.c.p.DCAwareRoundRobinPolicy        : Using data-center name \'DC1\' for DCAwareRoundRobinPolicy (if this is incorrect, please provide the correct datacenter name with DCAwareRoundRobinPolicy constructor)
2022-07-19 23:25:12.324  INFO 25652 --- [  restartedMain] com.datastax.driver.core.Cluster         : New Cassandra host /172.27.0.3:9042 added
2022-07-19 23:25:12.324  INFO 25652 --- [  restartedMain] com.datastax.driver.core.Cluster         : New Cassandra host /172.27.0.2:9042 added
2022-07-19 23:25:12.324  INFO 25652 --- [  restartedMain] com.datastax.driver.core.Cluster         : New Cassandra host /127.0.0.1:9044 added

然后,我最近在我的 docker-compose 文件中添加了“my-app”,但即使我等待节点状态工具确认所有节点都已启动,该应用程序也无法启动并立即关闭。

Caused by: java.net.ConnectException: Connection refused

Caused by: com.datastax.driver.core.exceptions.NoHostAvailableException: All host(s) tried for query failed (tried: /127.0.0.1:9042 

我与数据库连接的方式有问题吗?我想知道为什么嵌入式 tomcat 构建工作并且 docker 一立即关闭。我希望这里有人可以帮助我找到一种方法,让 docker-compose 构建在启动 my-app 之前等待所有 scylla 节点启动(我假设我可以使用 dockerfile 中的脚本来做到这一点?也许吧?),但我什至无法像使用 tomcat 一样在 docker 中启动应用程序。也许我在使用 docker 时缺少有关端口和主机的信息。

我可以尝试解决这个问题的任何想法?提前致谢!

使用应用程序编辑的 Docker 撰写文件:

  my-app:
    container_name: my-app
    build:
      context: .
      dockerfile: Dockerfile
    image: my-app
    ports:
      - 8082:8082
    depends_on:
      - scylla-node1
      - scylla-node2
      - scylla-node3
    networks:
      - scylla-network

    标签: spring-boot docker cassandra scylla


    【解决方案1】:

    您需要使用可从容器外部访问的联系点中的 IP 地址,而不是 localhost

    通常,它将是您为 CASSANDRA_RPC_ADDRESS(环境变量)或 rpc_address(在您的 yaml 中)配置的 IP 地址。

    如果您没有为容器设置 RPC 地址,则需要通过使用 CASSANDRA_BROADCAST_ADDRESSbroadcast_rpc_address 指定广播地址来告诉 Cassandra 向其他节点和客户端通告的 IP 地址。

    重要的是您需要使用可从 Spring Boot 应用程序访问的 IP 地址。干杯!

    【讨论】:

    • 嗨,埃里克,谢谢你的回复。实际上,我在 docker compose 文件中为每个节点添加了 --broadcast-rpc-address scylla-node1 命令。之后,我更改了联系点代码,它起作用了!谢谢!虽然我还有另一个问题。当我准备好所有节点时,有没有办法让“我的应用程序”只在 docker 中启动?我的意思是,它们都具有节点工具的联合国状态。因为发生的情况是“我的应用程序”在节点状态都正常之前无法启动。有没有办法在 dockerfile 中制作一个脚本来等待这种情况发生?
    • 这确实是一个单独的问题,特定于 Docker,因此最好创建一个新帖子。干杯!
    猜你喜欢
    • 2022-07-26
    • 1970-01-01
    • 1970-01-01
    • 2019-01-01
    • 2021-10-29
    • 1970-01-01
    • 2021-04-22
    • 2021-04-24
    • 2021-01-03
    相关资源
    最近更新 更多