Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Springboot elastic search health management : ConnectException: Connection refused

In my spring yaml file:

spring:
  application:
    name: myApp
  elasticsearch:
    jest:
      uris: ["http://myelasticserver:9200"]
      multi-threaded: true
      read-timeout: 10000

management:
  health:
    elasticsearch:
      indices: ["one","two"]
      response-timeout: 1000
      enabled: true

Thing is, the Jest client can be injected and used without any problem. But somehow, the health check always fails with this error:

Elasticsearch health check failed java.net.ConnectException: Connection refused

It seems like the URL "http://myelasticserver:9200" wasn't used, and health check use localhost:9200 instead.

Does anyone know what did I do wrong?

Thank you.

like image 646
Xitrum Avatar asked Jan 25 '19 10:01

Xitrum


3 Answers

The problem is indeed, as mst mentioned, that the actuator uses the RestClient. If you have configured the RestHighLevelClient, the configuration is not applied to the RestClient.

If you already have the RestHighLevelClient available, you can easily make a configured RestClient available as follows:

    @Bean(destroyMethod = "close")
    public RestClient restClient() {
        return restHighLevelClient().getLowLevelClient();
    }
like image 98
wardvijf Avatar answered Nov 06 '22 11:11

wardvijf


I had a same issue and I figured out what was a problem. For the health check java spring boot uses RestClient where I was using HighLevelRestClient for ES indexing/searching/deleting.

So, it seems you have also same case, whether you are using high or low (or tcp) level client for ES query but health check requires RestClient. So, the solution is to override RestClient bean with your env params. Add following to your configuration file (replace environment values with yours):

@Bean(destroyMethod = "close")
public RestClient restClient() {
    final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
    credentialsProvider.setCredentials(AuthScope.ANY,
            new UsernamePasswordCredentials(
                    environment.getProperty("elasticsearch.username"),
                    environment.getProperty("elasticsearch.password")));

    List<HttpHost> hosts = new ArrayList<>();
    hosts.add(new HttpHost(
            environment.getProperty("elasticsearch.hosts.host.name", String.class),
            environment.getProperty("elasticsearch.hosts.host.port", Integer.class),
            "http"));

    LOGGER.info("Elasticsearch connection establishing..." + hosts.toArray().toString());

    return RestClient.builder(Iterables.toArray(hosts, HttpHost.class))
            .setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider));
}

Let me see (plz post) your configuration if this does not work. Good luck!

References

  • http://www.matools.com/api/spring-boot -> ElasticsearchRestHealthIndicator
  • https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/index.html
like image 37
mst Avatar answered Nov 06 '22 11:11

mst


Spring boot elasticsearch needs to know to which port (and host) to connect for the health check. Add:

spring:
  elasticsearch:
    rest:
      uris: "myelasticserver:9200"
      #username: ""
      #password: ""

This is in addition to the config you already have. This is separate because many people, like me, use the (non-http) port 9300 of elasticsearch for the actual searches instead of your part of the config. I neither have management.health.elasticsearch. My total config for elasticsearch is:

spring:
  elasticsearch:
    rest:
      uris: "myelasticserver:9200"
  data:
    elasticsearch:
      cluster-nodes: "myelasticserver:9300"
      cluster-name: "my-cluster-name"
like image 22
Albert Hendriks Avatar answered Nov 06 '22 12:11

Albert Hendriks