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

测试代码配置远程Elasticsearch集群却尝试连接localhost:9200问题排查求助

问题分析与解决方案

从你的描述和日志来看,核心矛盾点在于:project-elasticsearch模块的测试能正常连接远程ES,但依赖它的project-api模块测试时,先成功连接了远程ES,随后却尝试连接localhost:9200并报错。结合日志中的SingleNodeHostProvider(属于Reactive Elasticsearch客户端组件)和你配置的RestHighLevelClient(同步客户端),我整理了以下几个可能的原因和对应的解决方案:

1. Reactive Elasticsearch客户端未配置,触发默认localhost连接

你的日志中出现的SingleNodeHostException是Reactive Elasticsearch客户端的报错,而你仅配置了同步的RestHighLevelClient。这说明project-api中可能存在以下情况:

  • 引入了spring-boot-starter-data-elasticsearch-reactive或spring-data-elasticsearch-reactive依赖;
  • 代码中使用了Reactive风格的ES操作类(比如ReactiveElasticsearchRepository、ReactiveElasticsearchTemplate)。

当Reactive客户端没有被显式配置时,会自动使用默认的localhost:9200地址,这就是报错的根源。

解决方案:

  • 如果不需要Reactive客户端:移除project-api中所有Reactive Elasticsearch相关的依赖,检查build.gradle中是否有类似如下依赖并删除:
    implementation 'org.springframework.boot:spring-boot-starter-data-elasticsearch-reactive'
    
  • 如果需要使用Reactive客户端:在你的ES配置类中添加Reactive客户端的配置Bean,和同步客户端保持一致的远程地址:
    @Bean
    public ReactiveElasticsearchClient reactiveElasticsearchClient(ElasticsearchProperty elasticsearchProperty) {
        ConnectionProperty connProp = elasticsearchProperty.getContents().getConnectionProperty();
        String hostAndPort = new HttpHost(connProp.getHosts(), Integer.parseInt(connProp.getPorts())).toHostString();
        
        ClientConfiguration clientConfiguration = ClientConfiguration.builder()
            .connectedTo(hostAndPort)
            .withBasicAuth(connProp.getUser(), connProp.getPassword()) // 配置账号密码
            .withConnectTimeout(Duration.ofMillis(connProp.getConnectionTimeout()))
            .withSocketTimeout(Duration.ofMillis(connProp.getSocketTimeout()))
            .build();
        
        return ReactiveRestClients.create(clientConfiguration);
    }
    

2. project-api未正确加载远程ES配置文件

project-elasticsearch能正常加载elasticsearch-local.yml,但project-api可能因为配置文件路径、Profile激活问题,没有正确读取到远程ES的配置,导致部分组件(比如Reactive客户端)使用默认值。

解决方案:

  • 确认project-api的测试类上是否指定了配置文件路径,比如添加:
    @TestPropertySource(locations = "classpath:elasticsearch-local.yml")
    
  • 检查project-api的resources目录下是否存在elasticsearch-local.yml,或者通过Gradle配置确保project-elasticsearch的配置文件被正确引入到project-api的classpath中:
    // 在project-api的build.gradle中添加
    sourceSets {
        main {
            resources {
                srcDirs += project(':project-elasticsearch').sourceSets.main.resources
            }
        }
        test {
            resources {
                srcDirs += project(':project-elasticsearch').sourceSets.test.resources
            }
        }
    }
    
  • 确认测试环境是否激活了正确的Profile,如果配置文件是基于Profile的,需要在测试类上添加@ActiveProfiles("local")。

3. 测试上下文的配置覆盖问题

project-api的测试类可能没有正确导入project-elasticsearch中的ES配置类,或者自身定义了冲突的ES配置Bean,导致远程配置被覆盖。

解决方案:

  • 在project-api的测试类上显式导入project-elasticsearch的配置类:
    @Import(ElasticsearchConfig.class) // 替换成你实际的配置类名
    @SpringBootTest
    public class YourApiTest {
        // ...
    }
    
  • 检查测试类中是否存在自定义的@Configuration类,里面是否定义了ES相关的Bean,如果有,删除或修改为使用远程配置。

额外验证点

你可以在project-api的测试中添加一段代码,打印当前加载的ES配置,确认配置是否正确读取:

@Autowired
private ElasticsearchProperty elasticsearchProperty;

@Test
public void printEsConfig() {
    System.out.println("ES Host: " + elasticsearchProperty.getContents().getConnectionProperty().getHosts());
    System.out.println("ES Port: " + elasticsearchProperty.getContents().getConnectionProperty().getPorts());
}

如果打印出来的是远程地址,那基本可以确定是Reactive客户端未配置的问题;如果打印的是默认值,那就是配置文件加载的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 09:52:28