ElasticSearch健康检查localhost:9200 not reachable
项目场景:项目使用了ElasticSearch【后续简称Es】,配置了Es的相关配置,通过spring的健康检查端点判断服务运行情况。项目未通过reactor的方式使用Es。问题描述:系统配置文件配置如下:spring:elasticsearch:rest:uris: http://xxxx:9200,http://xxxx:9200,http://xxxx:9200username: ela
项目场景:
项目使用了ElasticSearch【后续简称Es】,配置了Es的相关配置,通过spring的健康检查端点判断服务运行情况。项目未通过reactor的方式使用Es。
问题描述:
系统配置文件配置如下:
spring:
elasticsearch:
rest:
uris: http://xxxx:9200,http://xxxx:9200,http://xxxx:9200
username: elastic
password: ${pwd.elastic}
调用/actuator/health,发现状态为DOWN。控制台报错如下:
2021-06-23 11:32:32.827 WARN [] 30680 --- [ctor-http-nio-2] a.e.ElasticsearchReactiveHealthIndicator : Elasticsearch health check failed
org.springframework.data.elasticsearch.client.NoReachableHostException: Host 'localhost:9200' not reachable. Cluster state is offline.
at org.springframework.data.elasticsearch.client.reactive.SingleNodeHostProvider.lambda$null$4(SingleNodeHostProvider.java:106)
原因分析:
从报错上看,这个健康检查明显使用的是响应式的健康检查。
通过debug发现host是localhost,并非配置文件中配置的地址:
client中的host配置是通过下面的配置进行配置的:
spring:
data:
elasticsearch:
client:
reactive:
endpoints: http://xxxx:9200,http://xxxx:9200,http://xxxx:9200
username: elastic
password: ${pwd.elastic}
配置上之后可以解决控制台报错,但是调用/actuator/health 会卡死。
继续排查:
从堆栈上看出这个bean是通过ElasticSearchReactiveHealthContributorAutoConfiguration 注入的:
package org.springframework.boot.actuate.autoconfigure.elasticsearch;
import java.util.Map;
import org.springframework.boot.actuate.autoconfigure.health.CompositeReactiveHealthContributorConfiguration;
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
import org.springframework.boot.actuate.elasticsearch.ElasticsearchReactiveHealthIndicator;
import org.springframework.boot.actuate.health.ReactiveHealthContributor;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRestClientAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient;
import reactor.core.publisher.Flux;
@Configuration(
proxyBeanMethods = false
)
@ConditionalOnClass({ReactiveElasticsearchClient.class, Flux.class})
@ConditionalOnBean({ReactiveElasticsearchClient.class})
@ConditionalOnEnabledHealthIndicator("elasticsearch")
@AutoConfigureAfter({ReactiveElasticsearchRestClientAutoConfiguration.class})
public class ElasticSearchReactiveHealthContributorAutoConfiguration extends CompositeReactiveHealthContributorConfiguration<ElasticsearchReactiveHealthIndicator, ReactiveElasticsearchClient> {
public ElasticSearchReactiveHealthContributorAutoConfiguration() {
}
@Bean
@ConditionalOnMissingBean(
name = {"elasticsearchHealthIndicator", "elasticsearchHealthContributor"}
)
public ReactiveHealthContributor elasticsearchHealthContributor(Map<String, ReactiveElasticsearchClient> clients) {
return (ReactiveHealthContributor)this.createContributor(clients);
}
}
也就是项目只要依赖的Flux相关的的内容就会创建这个bean。同时项目中也有:
org.springframework.boot.actuate.autoconfigure.elasticsearch.ElasticSearchRestHealthContributorAutoConfiguration
这里会注入rest方式的健康检查bean。
两者同时存在时,健康检查取用了响应式的检查类。
解决方案:
从上面的分析可以看出解决办法有两个:
方案1、排除Flux相关依赖;
方案2、排除ElasticSearchReactiveHealthContributorAutoConfiguration。
我这采用的第二种,在启动类中排除该依赖即可:
@SpringBootApplication(exclude=ElasticSearchReactiveHealthContributorAutoConfiguration.class)
更多推荐
所有评论(0)