前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >聊聊springboot elasticsearch healthIndicator

聊聊springboot elasticsearch healthIndicator

原创
作者头像
code4it
发布2019-04-18 22:49:08
2K0
发布2019-04-18 22:49:08
举报
文章被收录于专栏:码匠的流水账

本文主要研究一下springboot elasticsearch healthIndicator

ElasticsearchHealthIndicatorProperties

spring-boot-actuator-autoconfigure-2.1.4.RELEASE-sources.jar!/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticsearchHealthIndicatorProperties.java

代码语言:javascript
复制
@ConfigurationProperties(prefix = "management.health.elasticsearch",
        ignoreUnknownFields = false)
public class ElasticsearchHealthIndicatorProperties {
​
    /**
     * Comma-separated index names.
     */
    private List<String> indices = new ArrayList<>();
​
    /**
     * Time to wait for a response from the cluster.
     */
    private Duration responseTimeout = Duration.ofMillis(100);
​
    public List<String> getIndices() {
        return this.indices;
    }
​
    public void setIndices(List<String> indices) {
        this.indices = indices;
    }
​
    public Duration getResponseTimeout() {
        return this.responseTimeout;
    }
​
    public void setResponseTimeout(Duration responseTimeout) {
        this.responseTimeout = responseTimeout;
    }
​
}
  • ElasticsearchHealthIndicatorProperties提供了indices,responseTimeout两个配置项

ElasticSearchClientHealthIndicatorAutoConfiguration

spring-boot-actuator-autoconfigure-2.1.4.RELEASE-sources.jar!/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticSearchClientHealthIndicatorAutoConfiguration.java

代码语言:javascript
复制
@Configuration
@ConditionalOnClass(Client.class)
@ConditionalOnBean(Client.class)
@ConditionalOnEnabledHealthIndicator("elasticsearch")
@AutoConfigureBefore(HealthIndicatorAutoConfiguration.class)
@AutoConfigureAfter(ElasticsearchAutoConfiguration.class)
@EnableConfigurationProperties(ElasticsearchHealthIndicatorProperties.class)
public class ElasticSearchClientHealthIndicatorAutoConfiguration extends
        CompositeHealthIndicatorConfiguration<ElasticsearchHealthIndicator, Client> {
​
    private final Map<String, Client> clients;
​
    private final ElasticsearchHealthIndicatorProperties properties;
​
    public ElasticSearchClientHealthIndicatorAutoConfiguration(
            Map<String, Client> clients,
            ElasticsearchHealthIndicatorProperties properties) {
        this.clients = clients;
        this.properties = properties;
    }
​
    @Bean
    @ConditionalOnMissingBean(name = "elasticsearchHealthIndicator")
    public HealthIndicator elasticsearchHealthIndicator() {
        return createHealthIndicator(this.clients);
    }
​
    @Override
    protected ElasticsearchHealthIndicator createHealthIndicator(Client client) {
        Duration responseTimeout = this.properties.getResponseTimeout();
        return new ElasticsearchHealthIndicator(client,
                (responseTimeout != null) ? responseTimeout.toMillis() : 100,
                this.properties.getIndices());
    }
​
}
  • ElasticSearchClientHealthIndicatorAutoConfiguration创建的是ElasticsearchHealthIndicator(elasticsearch),它是通过org.elasticsearch.client.Client去检测的

ElasticsearchHealthIndicator

spring-boot-actuator-2.1.4.RELEASE-sources.jar!/org/springframework/boot/actuate/elasticsearch/ElasticsearchHealthIndicator.java

代码语言:javascript
复制
public class ElasticsearchHealthIndicator extends AbstractHealthIndicator {
​
    private static final String[] ALL_INDICES = { "_all" };
​
    private final Client client;
​
    private final String[] indices;
​
    private final long responseTimeout;
​
    /**
     * Create a new {@link ElasticsearchHealthIndicator} instance.
     * @param client the Elasticsearch client
     * @param responseTimeout the request timeout in milliseconds
     * @param indices the indices to check
     */
    public ElasticsearchHealthIndicator(Client client, long responseTimeout,
            List<String> indices) {
        this(client, responseTimeout,
                (indices != null) ? StringUtils.toStringArray(indices) : null);
    }
​
    /**
     * Create a new {@link ElasticsearchHealthIndicator} instance.
     * @param client the Elasticsearch client
     * @param responseTimeout the request timeout in milliseconds
     * @param indices the indices to check
     */
    public ElasticsearchHealthIndicator(Client client, long responseTimeout,
            String... indices) {
        super("Elasticsearch health check failed");
        this.client = client;
        this.responseTimeout = responseTimeout;
        this.indices = indices;
    }
​
    @Override
    protected void doHealthCheck(Health.Builder builder) throws Exception {
        ClusterHealthRequest request = Requests.clusterHealthRequest(
                ObjectUtils.isEmpty(this.indices) ? ALL_INDICES : this.indices);
        ClusterHealthResponse response = this.client.admin().cluster().health(request)
                .actionGet(this.responseTimeout);
        switch (response.getStatus()) {
        case GREEN:
        case YELLOW:
            builder.up();
            break;
        case RED:
        default:
            builder.down();
            break;
        }
        builder.withDetail("clusterName", response.getClusterName());
        builder.withDetail("numberOfNodes", response.getNumberOfNodes());
        builder.withDetail("numberOfDataNodes", response.getNumberOfDataNodes());
        builder.withDetail("activePrimaryShards", response.getActivePrimaryShards());
        builder.withDetail("activeShards", response.getActiveShards());
        builder.withDetail("relocatingShards", response.getRelocatingShards());
        builder.withDetail("initializingShards", response.getInitializingShards());
        builder.withDetail("unassignedShards", response.getUnassignedShards());
    }
​
}
  • ElasticsearchHealthIndicator继承了AbstractHealthIndicator,这里如果不指定indices的话,默认是ALL_INDICES(_all);doHealthCheck方法使用client.admin().cluster().health(request)来进行请求,之后根据ClusterHealthResponse的状态来决定是up还是down,如果是GREEN或YELLOW则返回Status.UP,如果是RED则返回Status.DOWN

ElasticSearchRestHealthIndicatorAutoConfiguration

spring-boot-actuator-autoconfigure-2.1.4.RELEASE-sources.jar!/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticSearchRestHealthIndicatorAutoConfiguration.java

代码语言:javascript
复制
@Configuration
@ConditionalOnClass(RestClient.class)
@ConditionalOnBean(RestClient.class)
@ConditionalOnEnabledHealthIndicator("elasticsearch")
@AutoConfigureBefore(HealthIndicatorAutoConfiguration.class)
@AutoConfigureAfter({ RestClientAutoConfiguration.class,
        ElasticSearchClientHealthIndicatorAutoConfiguration.class })
public class ElasticSearchRestHealthIndicatorAutoConfiguration extends
        CompositeHealthIndicatorConfiguration<ElasticsearchRestHealthIndicator, RestClient> {
​
    private final Map<String, RestClient> clients;
​
    public ElasticSearchRestHealthIndicatorAutoConfiguration(
            Map<String, RestClient> clients) {
        this.clients = clients;
    }
​
    @Bean
    @ConditionalOnMissingBean(name = "elasticsearchRestHealthIndicator")
    public HealthIndicator elasticsearchRestHealthIndicator() {
        return createHealthIndicator(this.clients);
    }
​
    @Override
    protected ElasticsearchRestHealthIndicator createHealthIndicator(RestClient client) {
        return new ElasticsearchRestHealthIndicator(client);
    }
​
}
  • ElasticSearchRestHealthIndicatorAutoConfiguration创建的是ElasticsearchRestHealthIndicator(elasticsearchRest),它是通过org.elasticsearch.client.RestClient去检测的

ElasticsearchRestHealthIndicator

spring-boot-actuator-2.1.4.RELEASE-sources.jar!/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicator.java

代码语言:javascript
复制
public class ElasticsearchRestHealthIndicator extends AbstractHealthIndicator {
​
    private static final String RED_STATUS = "red";
​
    private final RestClient client;
​
    private final JsonParser jsonParser;
​
    public ElasticsearchRestHealthIndicator(RestClient client) {
        super("Elasticsearch health check failed");
        this.client = client;
        this.jsonParser = JsonParserFactory.getJsonParser();
    }
​
    @Override
    protected void doHealthCheck(Health.Builder builder) throws Exception {
        Response response = this.client
                .performRequest(new Request("GET", "/_cluster/health/"));
        StatusLine statusLine = response.getStatusLine();
        if (statusLine.getStatusCode() != HttpStatus.SC_OK) {
            builder.down();
            builder.withDetail("statusCode", statusLine.getStatusCode());
            builder.withDetail("reasonPhrase", statusLine.getReasonPhrase());
            return;
        }
        try (InputStream inputStream = response.getEntity().getContent()) {
            doHealthCheck(builder,
                    StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8));
        }
    }
​
    private void doHealthCheck(Health.Builder builder, String json) {
        Map<String, Object> response = this.jsonParser.parseMap(json);
        String status = (String) response.get("status");
        if (RED_STATUS.equals(status)) {
            builder.outOfService();
        }
        else {
            builder.up();
        }
        builder.withDetails(response);
    }
​
}
  • ElasticsearchRestHealthIndicator继承了AbstractHealthIndicator,构造器通过JsonParserFactory.getJsonParser()创建了JsonParser
  • doHealthCheck方法通过RestClient.performRequest(new Request("GET", "/_cluster/health/"))进行请求,如果http response status code不是HttpStatus.SC_OK,直接返回Status.DOWN;如果是HttpStatus.SC_OK再进一步解析json判断
  • 私有的doHealthCheck方法通过jsonParser.parseMap(json)解析返回json为Map,然后取status字段,如果是red则返回Status.OUT_OF_SERVICE,否则返回Status.UP

GET /_cluster/health/在http response status code为200的情况下返回的结构实例如下:

代码语言:javascript
复制
{
  "cluster_name" : "docker-cluster",
  "status" : "yellow",
  "timed_out" : false,
  "number_of_nodes" : 1,
  "number_of_data_nodes" : 1,
  "active_primary_shards" : 8,
  "active_shards" : 8,
  "relocating_shards" : 0,
  "initializing_shards" : 0,
  "unassigned_shards" : 6,
  "delayed_unassigned_shards" : 0,
  "number_of_pending_tasks" : 0,
  "number_of_in_flight_fetch" : 0,
  "task_max_waiting_in_queue_millis" : 0,
  "active_shards_percent_as_number" : 57.14285714285714
}

ElasticSearchJestHealthIndicatorAutoConfiguration

spring-boot-actuator-autoconfigure-2.1.4.RELEASE-sources.jar!/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticSearchJestHealthIndicatorAutoConfiguration.java

代码语言:javascript
复制
@Configuration
@ConditionalOnClass(JestClient.class)
@ConditionalOnBean(JestClient.class)
@ConditionalOnEnabledHealthIndicator("elasticsearch")
@AutoConfigureBefore(HealthIndicatorAutoConfiguration.class)
@AutoConfigureAfter({ JestAutoConfiguration.class,
        ElasticSearchClientHealthIndicatorAutoConfiguration.class })
public class ElasticSearchJestHealthIndicatorAutoConfiguration extends
        CompositeHealthIndicatorConfiguration<ElasticsearchJestHealthIndicator, JestClient> {
​
    private final Map<String, JestClient> clients;
​
    public ElasticSearchJestHealthIndicatorAutoConfiguration(
            Map<String, JestClient> clients) {
        this.clients = clients;
    }
​
    @Bean
    @ConditionalOnMissingBean(name = "elasticsearchHealthIndicator")
    public HealthIndicator elasticsearchHealthIndicator() {
        return createHealthIndicator(this.clients);
    }
​
    @Override
    protected ElasticsearchJestHealthIndicator createHealthIndicator(JestClient client) {
        return new ElasticsearchJestHealthIndicator(client);
    }
​
}
  • ElasticSearchJestHealthIndicatorAutoConfiguration创建的是ElasticsearchJestHealthIndicator(elasticsearch),它是通过io.searchbox.client.JestClient去检测的

ElasticsearchJestHealthIndicator

spring-boot-actuator-2.1.4.RELEASE-sources.jar!/org/springframework/boot/actuate/elasticsearch/ElasticsearchJestHealthIndicator.java

代码语言:javascript
复制
public class ElasticsearchJestHealthIndicator extends AbstractHealthIndicator {
​
    private final JestClient jestClient;
​
    private final JsonParser jsonParser = JsonParserFactory.getJsonParser();
​
    public ElasticsearchJestHealthIndicator(JestClient jestClient) {
        super("Elasticsearch health check failed");
        this.jestClient = jestClient;
    }
​
    @Override
    protected void doHealthCheck(Health.Builder builder) throws Exception {
        JestResult healthResult = this.jestClient
                .execute(new io.searchbox.cluster.Health.Builder().build());
        if (healthResult.getResponseCode() != 200 || !healthResult.isSucceeded()) {
            builder.down();
            builder.withDetail("statusCode", healthResult.getResponseCode());
        }
        else {
            Map<String, Object> response = this.jsonParser
                    .parseMap(healthResult.getJsonString());
            String status = (String) response.get("status");
            if (status.equals(io.searchbox.cluster.Health.Status.RED.getKey())) {
                builder.outOfService();
            }
            else {
                builder.up();
            }
            builder.withDetails(response);
        }
    }
​
}
  • ElasticsearchJestHealthIndicator继承了AbstractHealthIndicator,构造器通过接收JestClient
  • doHealthCheck方法通过jestClient.execute(new io.searchbox.cluster.Health.Builder().build())进行请求,如果http response status code不是200,或者healthResult.isSucceeded()不是true则直接返回Status.DOWN
  • 如果http response status code是200且healthResult.isSucceeded()为true则再进一步通过jsonParser.parseMap(json)解析返回json为Map,然后取status字段,如果是io.searchbox.cluster.Health.Status.RED.getKey()则返回Status.OUT_OF_SERVICE,否则返回Status.UP

小结

  • springboot提供了三个elasticsearch的healthIndicator配置,分别是ElasticSearchClientHealthIndicatorAutoConfiguration、ElasticSearchRestHealthIndicatorAutoConfiguration、ElasticSearchJestHealthIndicatorAutoConfiguration
  • ElasticSearchClientHealthIndicatorAutoConfiguration创建的是ElasticsearchHealthIndicator(elasticsearch),它是通过org.elasticsearch.client.Client去检测的
  • ElasticSearchRestHealthIndicatorAutoConfiguration创建的是ElasticsearchRestHealthIndicator(elasticsearchRest),它是通过org.elasticsearch.client.RestClient去检测的
  • ElasticSearchJestHealthIndicatorAutoConfiguration创建的是ElasticsearchJestHealthIndicator(elasticsearch),它是通过io.searchbox.client.JestClient去检测的
  • ElasticsearchHealthIndicatorProperties提供了indices,responseTimeout两个配置项,对于使用org.elasticsearch.client.Client的如果没有配置应用使用的indices,则使用ALL_INDICES(_all)去请求;而使用org.elasticsearch.client.RestClient或io.searchbox.client.JestClient的它们请求的是/_cluster/health/这个接口

doc

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ElasticsearchHealthIndicatorProperties
  • ElasticSearchClientHealthIndicatorAutoConfiguration
    • ElasticsearchHealthIndicator
    • ElasticSearchRestHealthIndicatorAutoConfiguration
      • ElasticsearchRestHealthIndicator
      • ElasticSearchJestHealthIndicatorAutoConfiguration
        • ElasticsearchJestHealthIndicator
        • 小结
        • doc
        相关产品与服务
        Elasticsearch Service
        腾讯云 Elasticsearch Service(ES)是云端全托管海量数据检索分析服务,拥有高性能自研内核,集成X-Pack。ES 支持通过自治索引、存算分离、集群巡检等特性轻松管理集群,也支持免运维、自动弹性、按需使用的 Serverless 模式。使用 ES 您可以高效构建信息检索、日志分析、运维监控等服务,它独特的向量检索还可助您构建基于语义、图像的AI深度应用。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档