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

Scala测试中无法连接Cassandra Docker容器问题求助

解决Scala Docker测试中Cassandra端口无法访问的问题

我来帮你排查这个问题!从你给出的容器状态来看,端口映射其实已经生效了(9042对应宿主机的33116,9160对应33115),问题大概率出在容器启动后Cassandra还没完全就绪就尝试连接,或者测试代码里没有正确获取映射后的随机端口。下面分两种测试库给出具体解决方案:

针对whisklabs/docker-it-scala的修改

这个库默认不会等待容器内的服务完全就绪,你需要手动添加就绪检查逻辑,同时确保使用映射后的端口:

  1. 添加就绪检查与超时
    修改容器定义,增加TCP端口就绪检查和足够的启动超时时间:

    val cassandraContainer: DockerContainer = DockerContainer("spotify/cassandra:latest")
      .withPorts(9042 -> None, 9060 -> None)
      .withReadyChecker(DockerReadyChecker.TcpPortReady(9042))
      .withStartupTimeout(60.seconds) // Cassandra启动较慢,给足时间
    
  2. 获取正确的连接端口
    测试代码中连接Cassandra时,不要直接用9042,而是通过容器获取映射后的宿主机端口:

    val cassandraPort = cassandraContainer.mappedPort(9042)
    val session = CassandraConnector(s"localhost:$cassandraPort").connect()
    

针对testcontainers/testcontainers-scala的修改

推荐使用Testcontainers专门的Cassandra模块,它会自动处理服务就绪检查,比GenericContainer更省心:

  1. 添加专用Cassandra容器依赖
    在你的sbt配置中添加Cassandra模块依赖(版本号根据你的Testcontainers版本调整):

    libraryDependencies += "com.dimafeng" %% "testcontainers-scala-cassandra" % "0.40.11" % Test
    
  2. 使用CassandraContainer替代GenericContainer
    专用容器会自动等待Cassandra启动完成,并提供便捷的连接参数:

    import com.dimafeng.testcontainers.CassandraContainer
    
    override val container = CassandraContainer("spotify/cassandra:latest")
    
    // 在测试中获取连接信息
    val cassandraIp = container.containerIpAddress
    val cassandraPort = container.mappedPort(CassandraContainer.CQL_PORT)
    

如果坚持要用GenericContainer,需要手动添加等待策略:

override val container = GenericContainer(
  "spotify/cassandra:latest",
  exposedPorts = Seq(9042, 9160)
)
  .withWaitStrategy(Wait.forListeningPort())
  .withWaitStrategy(Wait.forCommand("cqlsh -e 'describe keyspaces'")) // 验证CQL服务可用
  .withStartupTimeout(Duration.ofMinutes(2))

通用验证步骤

  1. 手动验证镜像可用性
    先手动启动容器,等待几分钟后用cqlsh测试连接,确认镜像本身没问题:

    docker run -p 9042:9042 spotify/cassandra:latest
    # 等待约2分钟后执行
    cqlsh localhost 9042
    
  2. 确认测试代码中端口使用正确
    无论用哪个库,都不要硬编码9042,必须通过容器API获取映射后的宿主机端口,因为测试库默认使用随机端口映射避免冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 10:02:07