如何用DataStax Enterprise Cassandra搭建Test Container?遇超时问题求助
解决TestContainers启动DSE容器超时问题
出现ConditionTimeoutException的核心原因是:TestContainers的CassandraContainer默认健康检查逻辑为开源Cassandra设计,而DSE(DataStax Enterprise)的启动流程、服务组件与就绪判断逻辑和开源版存在差异,导致容器启动后健康检查不通过,最终触发超时。
以下是具体修复步骤和修改后的代码:
关键修复点
- 添加DSE许可证环境变量:DSE容器启动必须接受许可证协议,否则服务会直接退出,这是最容易忽略的前提条件。
- 禁用非必要DSE服务:DSE默认会启动Spark、Search、Graph等组件,大幅增加启动时间,测试场景下关闭这些服务可加快启动速度。
- 替换健康检查策略:默认健康检查无法正确识别DSE的就绪状态,改用等待CQL端口连通+执行验证CQL命令的组合策略。
- 修正认证配置:DSE 5.1默认启用认证,需使用默认凭证
cassandra/cassandra,或通过环境变量关闭认证。
修改后的完整代码
@TestConfiguration class TestContainer { private static final String ROC_KEYSPACE = "cksdgmdp1"; private static CassandraContainer cassandraRocContainer; private static final String DSE_IMAGE_VERSION = "artifactory.aexp.com/dockerproxy/datastax/dse-server:5.1.10"; @BeforeAll static void setupCassandraConnectionProperties() { System.setProperty("spring.profiles.active", "e0"); System.setProperty("spring.profiles.env", "e0"); } @Bean("cassandraRocSession") public CassandraSession getCassandraRocSession() { DockerImageName myImage = DockerImageName.parse(DSE_IMAGE_VERSION) .asCompatibleSubstituteFor("cassandra"); cassandraRocContainer = (CassandraContainer) new CassandraContainer(myImage) // 必须添加:接受DSE许可证 .withEnv("DS_LICENSE", "accept") // 禁用非必要服务,加快启动 .withEnv("DSE_SPARK_ENABLED", "false") .withEnv("DSE_SEARCH_ENABLED", "false") .withEnv("DSE_GRAPH_ENABLED", "false") // 替换健康检查:先等端口连通,再执行CQL验证服务就绪 .waitingFor(Wait.forListeningPort()) .waitingFor(Wait.forExec("cqlsh -e 'SELECT now() FROM system.local;'")) // 延长启动超时时间(可选,按需调整) .withStartupTimeout(Duration.ofMinutes(2)) .withInitScript(getCqlScript(ROC_KEYSPACE)) .withExposedPorts(9042); cassandraRocContainer.start(); // DSE默认认证凭证为cassandra/cassandra Cluster cluster = Cluster.builder() .addContactPoint(cassandraRocContainer.getHost()) .withPort(cassandraRocContainer.getMappedPort(9042)) .withCredentials("cassandra", "cassandra") .build(); Session session = cluster.connect(ROC_KEYSPACE); return new CassandraSession(session, ROC_KEYSPACE); } public String getCqlScript(String keyspace) { return String.format("%s.cql", keyspace); } @AfterAll static void shutdown() { if (cassandraRocContainer != null) { cassandraRocContainer.close(); } } }
额外排查建议
- 手动测试镜像可用性:在本地Docker环境执行
docker run -e DS_LICENSE=accept artifactory.aexp.com/dockerproxy/datastax/dse-server:5.1.10,确认容器能正常启动。 - 检查初始化脚本:确认
cksdgmdp1.cql中没有DSE 5.1不兼容的语法。 - 调整超时时间:若仍超时,可进一步延长
withStartupTimeout的时长。
内容的提问来源于stack exchange,提问作者Cris Manrique
相关产品推荐
相关产品推荐

