本文主要研究一下springboot elasticsearch healthIndicator
spring-boot-actuator-autoconfigure-2.1.4.RELEASE-sources.jar!/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticsearchHealthIndicatorProperties.java
@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; } }
spring-boot-actuator-autoconfigure-2.1.4.RELEASE-sources.jar!/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticSearchClientHealthIndicatorAutoConfiguration.java
@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()); } }
elasticsearch
),它是通过org.elasticsearch.client.Client去检测的 spring-boot-actuator-2.1.4.RELEASE-sources.jar!/org/springframework/boot/actuate/elasticsearch/ElasticsearchHealthIndicator.java
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()); } }
_all _all
spring-boot-actuator-autoconfigure-2.1.4.RELEASE-sources.jar!/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticSearchRestHealthIndicatorAutoConfiguration.java
@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); } }
elasticsearchRest
),它是通过org.elasticsearch.client.RestClient去检测的 spring-boot-actuator-2.1.4.RELEASE-sources.jar!/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicator.java
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); } }
GET /_cluster/health/在http response status code为200的情况下返回的结构实例如下:
{ "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 }
spring-boot-actuator-autoconfigure-2.1.4.RELEASE-sources.jar!/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticSearchJestHealthIndicatorAutoConfiguration.java
@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); } }
elasticsearch
),它是通过io.searchbox.client.JestClient去检测的 spring-boot-actuator-2.1.4.RELEASE-sources.jar!/org/springframework/boot/actuate/elasticsearch/ElasticsearchJestHealthIndicator.java
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); } } }
elasticsearch elasticsearchRest elasticsearch _all