You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker中4节点Cassandra集群与Spring Boot连接报错求助

问题描述

我正在用docker-compose搭建4节点Cassandra集群,docker-compose配置如下:

version: "3.8"

services:
  cass1:
    image: cassandra:4
    container_name: cass1
    hostname: cass1
    networks:
      cass_netwrok:
        ipv4_address: 172.30.0.2
    expose:
      - 9042
    ports:
      - "9042:9042"
    environment:
      - CASSANDRA_CLUSTER_NAME=default
      - CASSANDRA_SEEDS=cass1
  cass2:
    image: cassandra:4
    container_name: cass2
    hostname: cass2
    networks:
      cass_netwrok:
        ipv4_address: 172.30.0.3
    expose:
      - 9042
    ports:
      - "9043:9042"
    environment:
      - CASSANDRA_CLUSTER_NAME=default
      - CASSANDRA_SEEDS=cass1
    depends_on:
      - cass1
  cass3:
    image: cassandra:4
    container_name: cass3
    hostname: cass3
    networks:
      cass_netwrok:
        ipv4_address: 172.30.0.4
    expose:
      - 9042
    ports:
      - "9044:9042"
    environment:
      - CASSANDRA_CLUSTER_NAME=default
      - CASSANDRA_SEEDS=cass1
    depends_on:
      - cass1
  cass4:
    expose:
      - 9042
    image: cassandra:4
    container_name: cass4
    hostname: cass4
    networks:
      cass_netwrok:
        ipv4_address: 172.30.0.5
    ports:
      - "9045:9042"
    environment:
      - CASSANDRA_CLUSTER_NAME=default
      - CASSANDRA_SEEDS=cass1
    depends_on:
      - cass1

networks:
  cass_netwrok:
    ipam:
      driver: default
      config:
        - subnet: 172.30.0.0/16

集群初步可用:能通过localhost:9042连接第一个节点,创建keyspace和表,且在localhost:9043能看到相同的表。但Spring Boot应用连接时出现报错,关键错误包括:

  • Found invalid row in system.peers_v2 for peer: /172.30.0.3. This is likely a gossip or snitch issue
  • Error while opening new channel (ConnectionInitException: ... failed to send request (java.nio.channels.NotYetConnectedException))

Spring配置:

spring:
  data:
    cassandra:
      keyspace-name: events
      contact-points:
        - "localhost:9042"
        - "localhost:9043"
        - "localhost:9044"
        - "localhost:9045"

Cassandra配置类:

@Configuration
@EnableCassandraRepositories(basePackages = "com.eternal.nosqltask3.repository")
public class CassandraConfig extends AbstractCassandraConfiguration {

    @Value("${spring.data.cassandra.keyspace-name}")
    private String keyspace;
    @Override
    protected String getKeyspaceName() {
        return keyspace;
    }
}

请问搭建集群和Spring连接时遗漏了什么配置,如何解决这些错误?


解决方案

错误原因分析

  1. Cassandra地址广播问题:Cassandra节点默认会向客户端广播自己的容器内部IP(如172.30.0.3)和默认CQL端口9042,但宿主机并未映射这些容器内部端口,导致Spring Boot驱动尝试连接172.30.0.3:9042时无法建立连接,抛出NotYetConnectedException。
  2. 集群节点就绪检测缺失:depends_on仅保证容器启动顺序,不确保Cassandra服务完全就绪,可能导致后续节点未正确加入集群,引发gossip/snitch警告。

具体修复步骤

1. 修改docker-compose配置,配置Cassandra广播地址与端口

给每个Cassandra服务添加以下环境变量,让节点向外部客户端广播宿主机可访问的地址和映射端口:

# cass1的environment新增
- CASSANDRA_LISTEN_ADDRESS=cass1
- CASSANDRA_RPC_ADDRESS=0.0.0.0
- CASSANDRA_BROADCAST_ADDRESS=localhost
- CASSANDRA_BROADCAST_RPC_PORT=9042

# cass2的environment新增
- CASSANDRA_LISTEN_ADDRESS=cass2
- CASSANDRA_RPC_ADDRESS=0.0.0.0
- CASSANDRA_BROADCAST_ADDRESS=localhost
- CASSANDRA_BROADCAST_RPC_PORT=9043

# cass3的environment新增
- CASSANDRA_LISTEN_ADDRESS=cass3
- CASSANDRA_RPC_ADDRESS=0.0.0.0
- CASSANDRA_BROADCAST_ADDRESS=localhost
- CASSANDRA_BROADCAST_RPC_PORT=9044

# cass4的environment新增
- CASSANDRA_LISTEN_ADDRESS=cass4
- CASSANDRA_RPC_ADDRESS=0.0.0.0
- CASSANDRA_BROADCAST_ADDRESS=localhost
- CASSANDRA_BROADCAST_RPC_PORT=9045

参数说明:

  • CASSANDRA_LISTEN_ADDRESS:集群内部节点通信使用的地址(容器hostname)
  • CASSANDRA_RPC_ADDRESS:允许Cassandra接收外部连接的地址(设为0.0.0.0允许容器外访问)
  • CASSANDRA_BROADCAST_ADDRESS:向外部客户端广播的地址(宿主机localhost)
  • CASSANDRA_BROADCAST_RPC_PORT:向外部客户端广播的CQL端口(对应宿主机映射的端口)

2. 添加健康检测,确保节点就绪后再启动后续容器

在每个Cassandra服务中添加健康检测配置,并修改depends_on依赖条件:

# 在cass1服务中添加
healthcheck:
  test: ["CMD-SHELL", "cqlsh cass1 -e 'describe keyspaces' || exit 1"]
  interval: 30s
  timeout: 10s
  retries: 5

# 在cass2、cass3、cass4的depends_on中修改为
depends_on:
  cass1:
    condition: service_healthy

这样能保证后续节点在cass1完全就绪后再启动,避免集群节点加入失败。

3. 优化Spring Boot配置(可选)

驱动会自动从初始连接节点获取集群拓扑信息,因此只需配置一个初始接触点即可:

spring:
  data:
    cassandra:
      keyspace-name: events
      contact-points: "localhost:9042"

验证修复

  1. 停止并删除原有容器:docker-compose down -v
  2. 重新启动集群:docker-compose up -d
  3. 查看集群状态:docker exec -it cass1 nodetool status,确认所有节点状态为UN(正常)
  4. 启动Spring Boot应用,检查日志是否无连接错误

内容的提问来源于stack exchange,提问作者eternal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 15:03:35