赞
踩
为什么要写这一篇文章呢?其实随着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]
在使用TransportClient的官方文档中有说明,如果使用的ES集群名不是elasticsearch
,需要在Settings中设置cluster.name
;
所以,(第一)我们要检查一下配置TransportClient的地方有没有设置正确的集群名;
ES的版本迭代是真的快,并且每个版本之间的API变化特别大;所以很多时候版本之间的兼容性有待商榷;在我们开发的过程中建议引入的(第二)jar版本和服务器中ES的版本保持一致;
比如:我们测试环境用的es5.6.9,所以我在pom依赖中也统一管理ES版本为5.6.9;
对于一些小白,可能不知道ES的9200端口和9300端口差异;比如我们使用的ES-head插件 或者在ES高版本(比如7.X)中使用的RestHighLevelClient
使用的是ES的HTTP端口9200;而我们本篇文章中的TransportClient
则(第三)使用的TCP端口9300,注意:9300端口也在ES集群间通信使用。
在不使用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>
具体异常信息为:
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");
2> 也可以通过在ES配置类中添加构造器后置处理方法(@PostConstruct)(不过有时会不生效,最好还是用第一种方法),如下所示:
@PostConstruct
void init() {
System.setProperty("es.set.netty.runtime.available.processors", "false");
}
这个问题是真的奇葩,搞死人的感觉;我写完程序比较喜欢先本地跑一遍;我们UAT环境的ES是真集群(9个节点),然后我使用Mac直接走跳板机做端口映射连上了其中一台;
接着我直接调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的底层原理)!!!
还有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鉴权失败的问题。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。