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

Spring3.1.x+Testcontainer集成Elasticsearch8时连接被拒绝问题

问题:Spring 3.1 @ServiceConnection 配合Testcontainers Elasticsearch 8.x 连接被拒绝

我用CircleCI有段时间了,最近想升级集成测试,用上Testcontainers和Spring 3.1的新特性,尤其是@ServiceConnection。这个配置在MongoDB上没问题,但升级到Elasticsearch 8.1.x后,一直遇到循环连接被拒绝的问题。

我知道Elasticsearch 8默认开启安全功能,已经通过环境变量禁用了相关配置:

  • xpack.security.enabled=false
  • xpack.security.transport.ssl.enabled=false
  • xpack.security.http.ssl.enabled=false

另外我也清楚Testcontainers的Elasticsearch容器会设置默认密码,但我在application-test.yml里已经配置了用户名、密码和URI:

spring.elasticsearch.username: user
spring.elasticsearch.password: changeme
spring.elasticsearch.uris: http://localhost:9200

但看起来这些配置没生效——要么是@ServiceConnection注解忽略了它们,要么是容器没绑定到配置的地址。

我的测试类代码如下:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Testcontainers
@ActiveProfiles("test")
@Slf4j
public class FooControllerIT {
    @Container
    @ServiceConnection
    static MongoDBContainer mongoDBContainer = new MongoDBContainer(DockerImageName.parse("mongo").withTag("xxx"));
    
    @Container
    @ServiceConnection
    static ElasticsearchContainer elasticsearchContainer = new ElasticsearchContainer(DockerImageName.parse("docker.elastic.co/elasticsearch/elasticsearch")
            .withTag("8.x"))
            .withEnv("xpack.security.enabled", "false")
            .withEnv("xpack.security.transport.ssl.enabled","false")
            .withEnv("xpack.security.http.ssl.enabled","false");

    @Autowired
    private SomeController someController;

    @BeforeEach
    void setUp() {
        mongoDBContainer.start();
        elasticsearchContainer.start();// 启动时或访问属性时直接失败 <----
        Awaitility.await().atMost(Duration.ofMinutes(2)).until(() ->
                elasticsearchContainer.isRunning()); // <---- 根本执行不到这里,说明不是容器没启动完成的问题
        log.info("blabla"+elasticsearchContainer.isRunning()+","+elasticsearchContainer.isHostAccessible());
    }
}

我推测问题出在:程序试图连接配置里的9200端口,但Testcontainers实际给Elasticsearch容器分配了随机端口。

之前我用ApplicationContextInitializer手动设置属性解决过:

public static class ElasticConfigInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        elasticsearchContainer.start();
        await().atMost(120, TimeUnit.SECONDS).until(elasticsearchContainer::isRunning);
        String hostAddress = "http://" + elasticsearchContainer.getHttpHostAddress();
        TestPropertyValues.of(
                        "spring.elasticsearch.uris=" + hostAddress)
                .applyTo(applicationContext);
        log.info("finished Elastic config"+ elasticsearchContainer.getBoundPortNumbers()+","+elasticsearchContainer.getLogs());
    }
}

但我以为Spring 3.1的@ServiceConnection应该能自动处理这些,不需要手动写初始化器了?

错误堆栈信息:

Caused by: java.net.ConnectException: Connection refused: no further information
    at java.base/sun.nio.ch.Net.pollConnect(Native Method)
    at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672)
    at java.base/sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:946)
    at org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor.processEvent(DefaultConnectingIOReactor.java:174)
    at org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor.processEvents(DefaultConnectingIOReactor.java:148)
    at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor.execute(AbstractMultiworkerIOReactor.java:351)
    at org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager.execute(PoolingNHttpClientConnectionManager.java:221)
    at org.apache.http.impl.nio.client.CloseableHttpAsyncClientBase$1.run(CloseableHttpAsyncClientBase.java:64)
    at java.base/java.lang.Thread.run(Thread.java:833)

我希望不用手动覆盖配置,让@ServiceConnection正常工作,这可行吗?是不是我漏了什么配置?


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 18:15:17