背景

为什么要写这一篇文章呢?其实随着ES版本的迭代,大家现在新项目更习惯于用Spring-data-elasticsearch,但现实是我们不免要维护、迭代一些老项目;最近在做一个ES相关的需求,因为ES版本是5.6.X(属于老版本的了),spring-data-elasticsearch用不上,只能祖传TransportClient上场了。

u1s1看着官网随便搞搞也就跑起来了,不过想想那几个注意点,如果注意不到是真的恶心;好说不说的,我们TEST环境和UAT用的ES版本不同,并且TEST环境ES不需要授权、UAT环境使用x-pack做鉴权;我****,有问题就只能解决了。该文章用于事后总结,防止下次再遇到;

下面开始详细说一下导致​​None of the configured nodes are available​​的几种可能的原因。

详细异常如下:

org.elasticsearch.client.transport.NoNodeAvailableException: None of the configured nodes are available: [{#transport#-1}{jfVEwfw7QJqo1VWibatZ1g}{127.0.0.1}{127.0.0.1:9300}]
at org.elasticsearch.client.transport.TransportClientNodesService.ensureNodesAreAvailable(TransportClientNodesService.java:347) ~[elasticsearch-5.6.9.jar:5.6.9]
at org.elasticsearch.client.transport.TransportClientNodesService.execute(TransportClientNodesService.java:245) ~[elasticsearch-5.6.9.jar:5.6.9]
at org.elasticsearch.client.transport.TransportProxyClient.execute(TransportProxyClient.java:59) ~[elasticsearch-5.6.9.jar:5.6.9]
at org.elasticsearch.client.transport.TransportClient.doExecute(TransportClient.java:366) ~[elasticsearch-5.6.9.jar:5.6.9]
at org.elasticsearch.client.support.AbstractClient.execute(AbstractClient.java:408) ~[elasticsearch-5.6.9.jar:5.6.9]
at org.elasticsearch.client.support.AbstractClient.execute(AbstractClient.java:397) ~[elasticsearch-5.6.9.jar:5.6.9]
at org.elasticsearch.client.support.AbstractClient.search(AbstractClient.java:530) ~[elasticsearch-5.6.9.jar:5.6.9]

原因分析

1、ES集群名问题

在使用TransportClient的​​官方文档​​​中有说明,如果使用的ES集群名不是​​elasticsearch​​​,需要在Settings中设置​​cluster.name​​;

这些年遇到的Java连接ES报错原因汇总 >> None of the configured nodes are available:[{#transport#-1}{jfVEwfw7QJqo1VW_.net


所以,(第一)我们要检查一下配置TransportClient的地方有没有设置正确的集群名;

2、jar和ES版本问题

ES的版本迭代是真的快,并且每个版本之间的API变化特别大;所以很多时候版本之间的兼容性有待商榷;在我们开发的过程中建议引入的(第二)jar版本和服务器中ES的版本保持一致

比如:我们测试环境用的es5.6.9,所以我在pom依赖中也统一管理ES版本为5.6.9;

这些年遇到的Java连接ES报错原因汇总 >> None of the configured nodes are available:[{#transport#-1}{jfVEwfw7QJqo1VW_.net_02


这些年遇到的Java连接ES报错原因汇总 >> None of the configured nodes are available:[{#transport#-1}{jfVEwfw7QJqo1VW_java_03

3、TransportClient使用TCP端口9300

对于一些小白,可能不知道ES的9200端口和9300端口差异;比如我们使用的ES-head插件 或者在ES高版本(比如7.X)中使用的​​RestHighLevelClient​​​使用的是ES的HTTP端口9200;而我们本篇文章中的​​TransportClient​​则(第三)使用的TCP端口9300,注意:9300端口也在ES集群间通信使用。

4、jar包信息缺失

在不使用spring-data-elasticsearch时,我们需要在pom中引用三个jar,否者因为版本问题还可能会有transport-netty4-client相关的报错;

<!-- es使用的netty -->
<dependency>
<groupId>org.elasticsearch.plugin</groupId>
<artifactId>transport-netty4-client</artifactId>
<version>${elasticsearch}</version>
</dependency>

<!-- TransportClient -->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>${elasticsearch}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>

<!-- elasticsearch -->
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>${elasticsearch}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>

1)这里还可能会有Es的netty与Netty服务本身不兼容问题

具体异常信息为:

Caused by: java.lang.IllegalStateException: availableProcessors is already set to [4], rejecting [4]
at io.netty.util.NettyRuntime$AvailableProcessorsHolder.setAvailableProcessors(NettyRuntime.java:51)
at io.netty.util.NettyRuntime.setAvailableProcessors(NettyRuntime.java:87)
at org.elasticsearch.transport.netty4.Netty4Utils.setAvailableProcessors(Netty4Utils.java:82)
at org.elasticsearch.transport.netty4.Netty4Transport.<init>(Netty4Transport.java:138)
at org.elasticsearch.transport.Netty4Plugin.lambda$getTransports$0(Netty4Plugin.java:93)
at org.elasticsearch.client.transport.TransportClient.buildTemplate(TransportClient.java:174)
at org.elasticsearch.client.transport.TransportClient.<init>(TransportClient.java:265)
at org.elasticsearch.transport.client.PreBuiltTransportClient.<init>(PreBuiltTransportClient.java:130)
at org.elasticsearch.transport.client.PreBuiltTransportClient.<init>(PreBuiltTransportClient.java:116)
at org.elasticsearch.transport.client.PreBuiltTransportClient.<init>(PreBuiltTransportClient.java:106)
at org.springframework.data.elasticsearch.client.TransportClientFactoryBean.buildClient(TransportClientFactoryBean.java:91)
at org.springframework.data.elasticsearch.client.TransportClientFactoryBean.afterPropertiesSet(TransportClientFactoryBean.java:86)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1763)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1700)
... 82 more

解决措施:

1> 在SpringBoot启动类的main方法中添加如下信息:

System.setProperty("es.set.netty.runtime.available.processors", "false");

这些年遇到的Java连接ES报错原因汇总 >> None of the configured nodes are available:[{#transport#-1}{jfVEwfw7QJqo1VW_elasticsearch_04


2> 也可以通过在ES配置类中添加构造器后置处理方法(@PostConstruct)(不过有时会不生效,最好还是用第一种方法),如下所示:

@PostConstruct
void init() {
System.setProperty("es.set.netty.runtime.available.processors", "false");
}

5、节点通信问题

这个问题是真的奇葩,搞死人的感觉;我写完程序比较喜欢先本地跑一遍;我们UAT环境的ES是真集群(9个节点),然后我使用Mac直接走跳板机做端口映射连上了其中一台;

这些年遇到的Java连接ES报错原因汇总 >> None of the configured nodes are available:[{#transport#-1}{jfVEwfw7QJqo1VW_.net_05

接着我直接调Controller中的HTTP接口时,走到TransportClient#search()方法就会报错:

org.elasticsearch.client.transport.NoNodeAvailableException: None of the configured nodes are available: [{#transport#-1}{jfVEwfw7QJqo1VWibatZ1g}{127.0.0.1}{127.0.0.1:9300}]

最奇怪的就是,时不时的走到TransportClient#search()方法还能调通;于是试了几次,发现好像有规律,大约8、9次能成一次;

于是,推测是因为我本机只能和ES的一个节点通信,和其他节点通信的过程会出现问题;于是把项目打包走devops发到UAT,果然,程序没有问题(内心一顿苦笑,是时候复习一下ES的底层原理)!!!

6、客户端嗅探集群状态

还有​​client.transport.sniff = true​​开启 <使客户端去嗅探整个集群的状态>功能的坑:

当ES服务器监听(publish_address )使用内网服务器IP,而访问(bound_addresses )使用外网IP时,不要设置client.transport.sniff为true

因为在自动发现时会使用内网IP进行通信,导致无法连接到ES服务器;

设置不当也会遇到 ​​None of the configured nodes are available​​ 这个问题。

总结

上诉大致概括了大多数出现 ​​None of the configured nodes are available​​的原因和解决方案;下一篇文章我们聊一下es中集成了x-pack之后,Java Client鉴权失败的问题。