java连接docker容器elasticsearch:None of the configured nodes are available错误

错误背景

java代码没有变化,相同版本elasticsearch在本地启动后,java项目可以正常执行es的相关操作。
改用docker启动后,保持9300端口和cluster-name不变,在本地可以打开127.0.0.1:9200,并且可以使用http方式执行增删改查,但是启动java项目时却现如下错误:

NoNodeAvailableException[None of the configured nodes are available: [{#transport#-1}{IwNecF7LRCGevaJe61kiCQ}{127.0.0.1}{127.0.0.1:9300}]
]
	at org.elasticsearch.client.transport.TransportClientNodesService.ensureNodesAreAvailable(TransportClientNodesService.java:347)
	at org.elasticsearch.client.transport.TransportClientNodesService.execute(TransportClientNodesService.java:245)
	at org.elasticsearch.client.transport.TransportProxyClient.execute(TransportProxyClient.java:59)
	at org.elasticsearch.client.transport.TransportClient.doExecute(TransportClient.java:363)
	at org.elasticsearch.client.support.AbstractClient.execute(AbstractClient.java:408)
	at org.elasticsearch.action.ActionRequestBuilder.execute(ActionRequestBuilder.java:80)
	at org.elasticsearch.action.ActionRequestBuilder.execute(ActionRequestBuilder.java:54)
	at org.springframework.data.elasticsearch.core.ElasticsearchTemplate.getSearchResponse(ElasticsearchTemplate.java:937)
	at org.springframework.data.elasticsearch.core.ElasticsearchTemplate.doSearch(ElasticsearchTemplate.java:928)
	at org.springframework.data.elasticsearch.core.ElasticsearchTemplate.queryForPage(ElasticsearchTemplate.java:308)
	at org.springframework.data.elasticsearch.core.ElasticsearchTemplate.queryForPage(ElasticsearchTemplate.java:303)
	at org.springframework.data.elasticsearch.core.ElasticsearchTemplate.queryForPage(ElasticsearchTemplate.java:133)
	at org.springframework.data.elasticsearch.repository.support.AbstractElasticsearchRepository.search(AbstractElasticsearchRepository.java:214)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:359)
	at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:200)
...

错误检查

反复确认cluster-name和cluster-nodes没有问题后,只能进入容器内部检查配置了。
找到elasticsearch.yml文件,发现里面有个配置:

http.host: 0.0.0.0

这是允许外网访问的设置,此时才焕然大悟,本地的java项目还没有和es在一个docker集群里面,虽然端口通过主机进行了映射,但是在访问127.0.0.1:9300时,转发到容器时,已经算是外网访问了。
容器的内网ip,只有docker集群中的节点才能彼此访问,所以不可能通过容器ip:9300的方式填写cluster-nodes参数。那么为什么http.host: 0.0.0.09300端口不起作用呢,那是因为9200为http协议,9300作为tcp协议。

解决方案

知道问题所在,问题就好解决了。这里提供两种方案:

  1. 添加transport.host: 0.0.0.0,将通信方式也允许外网访问。
  2. http.host改为network.host,如果有network.host的情况下,transport.host会默认和network.host相同。

你可能感兴趣的:(bug与经验,elasticsearch,spring-boot)