Scala测试中无法连接Cassandra Docker容器问题求助
解决Scala Docker测试中Cassandra端口无法访问的问题
我来帮你排查这个问题!从你给出的容器状态来看,端口映射其实已经生效了(9042对应宿主机的33116,9160对应33115),问题大概率出在容器启动后Cassandra还没完全就绪就尝试连接,或者测试代码里没有正确获取映射后的随机端口。下面分两种测试库给出具体解决方案:
针对whisklabs/docker-it-scala的修改
这个库默认不会等待容器内的服务完全就绪,你需要手动添加就绪检查逻辑,同时确保使用映射后的端口:
添加就绪检查与超时
修改容器定义,增加TCP端口就绪检查和足够的启动超时时间:val cassandraContainer: DockerContainer = DockerContainer("spotify/cassandra:latest") .withPorts(9042 -> None, 9060 -> None) .withReadyChecker(DockerReadyChecker.TcpPortReady(9042)) .withStartupTimeout(60.seconds) // Cassandra启动较慢,给足时间获取正确的连接端口
测试代码中连接Cassandra时,不要直接用9042,而是通过容器获取映射后的宿主机端口:val cassandraPort = cassandraContainer.mappedPort(9042) val session = CassandraConnector(s"localhost:$cassandraPort").connect()
针对testcontainers/testcontainers-scala的修改
推荐使用Testcontainers专门的Cassandra模块,它会自动处理服务就绪检查,比GenericContainer更省心:
添加专用Cassandra容器依赖
在你的sbt配置中添加Cassandra模块依赖(版本号根据你的Testcontainers版本调整):libraryDependencies += "com.dimafeng" %% "testcontainers-scala-cassandra" % "0.40.11" % Test使用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))
通用验证步骤
手动验证镜像可用性
先手动启动容器,等待几分钟后用cqlsh测试连接,确认镜像本身没问题:docker run -p 9042:9042 spotify/cassandra:latest # 等待约2分钟后执行 cqlsh localhost 9042确认测试代码中端口使用正确
无论用哪个库,都不要硬编码9042,必须通过容器API获取映射后的宿主机端口,因为测试库默认使用随机端口映射避免冲突。
内容的提问来源于stack exchange,提问作者Atais
相关产品推荐
相关产品推荐

