SpringDataElasticsearch连接异常:None of the configured nodes are available
一步一步来:
(1)elasticsearch.yml中的网络配置简单说明:
# 官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-network.html
# 1 一共三个网络配置选项:
# 1.1 设置network相关设置后,http和transport将会继承此值,下面的设置同时暴露http和tcp到外网
network.host: "0.0.0.0"
# 1.2 仅暴露http协议
http.host: 0.0.0.0
# 1.3 仅暴露tcp协议
transport.host: "0.0.0.0"
# 2 可以分别配置端口port
http.port: 9200
transport: 9300
# 3 可以单独设置对外网开放的host
network.bind_host: 0.0.0.0
# 4 设置服务间的通讯host
network.publish_host: 0.0.0.0
(2)transport配置详细说明,参考:Elasticsearch节点间通信基础–Transport(一)
#端口号,默认是9300-9400
transport.port
#对外公布的端口,默认与transport.port相同
transport.publish_port
#host地址,默认为network.host
transport.host
#service绑定的地址,默认是transport.host或network.bind_host
transport.bind_host
#集群通信的地址,默认是transport.host或network.publish_host,有且只有一个
transport.publish_host
#连接超时时间
transport.connect_timeout
#是否在传输时进行压缩
transport.compress
#ping消息间隔时间,用来确认transport是否可用,默认是5s,可用设置为-1来代表禁止ping
transport.ping_schedule
#节点间保持连接很重要,因此尽量让transport连接不中断,transport.ping_schedule可用定时检测连接的可用性
#一般来说,集群节点之间的交互是本地的,相对网络带宽资源,CPU资源更重要,transport.compress配置设置为false可用减少资源损耗。
(3)SpringDataElasticsearch连接异常:None of the configured nodes are available
① 错误堆栈
......
[main] INFO org.springframework.data.elasticsearch.client.TransportClientFactoryBean - adding transport node : localhost:9300
[main] ERROR org.springframework.data.elasticsearch.repository.support.AbstractElasticsearchRepository - failed to load elasticsearch nodes : org.elasticsearch.client.transport.NoNodeAvailableException: None of the configured nodes are available: [{#transport#-1}{jS1zrK95T7CED3iUq4la1Q}{localhost}{127.0.0.1:9300}]
[Thread-1] INFO org.springframework.data.elasticsearch.client.TransportClientFactoryBean - Closing elasticSearch client
NoNodeAvailableException[None of the configured nodes are available: [{#transport#-1}{jS1zrK95T7CED3iUq4la1Q}{localhost}{127.0.0.1:9300}]
]
at org.elasticsearch.client.transport.TransportClientNodesService.ensureNodesAreAvailable(TransportClientNodesService.java:347)
......
② 网上一大堆相关问题解决就是配置第一步的网络设置,但是无效。我碰到这个问题时,单独使用transport client是能够通过tcp协议连接es容器的,但是换成Spring Data Elasticsearch就抛出上面的异常。最终在我的不懈努力和各种尝试下,修改配置文件 <elasticsearch:transport-client client-transport-sniff="false">
后终于成功解决:
修改applicationContext.xml,将client-transport-sniff设置为false:
<elasticsearch:transport-client id="esClient" cluster-name="yoko-es-cluster" cluster-nodes="localhost:9300" client-transport-sniff="false"/>
如果时SpringBoot的话(其实不需要设置):
spring:
data:
elasticsearch: # 旧版本的配置方式,版本对照:https://docs.spring.io/spring-data/elasticsearch/docs/3.2.0.RELEASE/reference/html/#preface.versions
cluster-nodes: localhost:9300
cluster-name: yoko-es-cluster
# Elasticsearch从7开始不推荐使用TransportClient客户端访问
# client:
# reactive: #https://docs.spring.io/spring-data/elasticsearch/docs/3.2.0.RELEASE/reference/html/#elasticsearch.clients.reactive
# endpoints: http://localhost:9200
# elasticsearch:
# rest:
# uris: http://localhost:9200
③ 现在知道了问题的根源,再去查阅资料,了解了根本:
client.transport.sniff
的作用是:使客户端去嗅探整个集群的状态,把集群中其它机器的ip地址加到客户端中。这样做的好处是,一般你不用手动设置集群里所有集群的ip到连接客户端,它会自动帮你添加,并且自动发现新加入集群的机器。
但使用该参数时有个注意事项。当ES服务器监听(publish_address )使用内网服务器IP,而访问(bound_addresses )使用外网IP时,不要设置client.transport.sniff为true。不设置client.transport.sniff时,默认为false(关闭客户端去嗅探整个集群的状态)。因为在自动发现时会使用内网IP进行通信,导致无法连接到ES服务器。因此此时需要直接使用addTransportAddress方法把集群中其它机器的ip地址加到客户端中。
④ 参考资料
- ‘java.lang.StackOverflowError’ exception. Cannot evaluate org.elasticsearch.common.inject.InjectorImpl.toString()
- https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-network.html
- Elasticsearch节点间通信基础–Transport(一)
- client.transport.sniff的使用方法
- client.transport.sniff配置引起的问题