Spring Boot 2.0无法连接ElasticSearch 5.5.0:NoNodeAvailableException异常
解决Spring Boot 2.0 + Spring Data Elasticsearch连接ES 5.5.0的NoNodeAvailableException问题
我之前也踩过类似的版本兼容+连接配置的坑,给你梳理几个关键排查点,应该能解决你的问题:
1. 强制对齐Elasticsearch依赖版本
Spring Boot 2.0.1默认依赖的Elasticsearch版本和5.5.0不匹配,这是最常见的诱因!你需要手动覆盖依赖,确保TransportClient版本和ES集群完全一致。
修改你的pom.xml,排除Spring Boot starter里自带的ES依赖,然后引入5.5.0版本的transport模块:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> <!-- 排除默认的ES依赖 --> <exclusions> <exclusion> <groupId>org.elasticsearch</groupId> <artifactId>elasticsearch</artifactId> </exclusion> <exclusion> <groupId>org.elasticsearch.client</groupId> <artifactId>transport</artifactId> </exclusion> </exclusions> </dependency> <!-- 引入和ES集群一致的5.5.0版本 --> <dependency> <groupId>org.elasticsearch</groupId> <artifactId>elasticsearch</artifactId> <version>5.5.0</version> </dependency> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>transport</artifactId> <version>5.5.0</version> </dependency>
2. 正确配置TransportClient Bean
Spring Data Elasticsearch 3.0.x(对应Spring Boot 2.0)的TransportClient配置要注意细节,比如节点地址、集群名称、嗅探设置。
创建一个配置类:
import org.elasticsearch.client.transport.TransportClient; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.TransportAddress; import org.elasticsearch.transport.client.PreBuiltTransportClient; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; import java.net.InetAddress; import java.net.UnknownHostException; @Configuration public class ElasticsearchConfig { @Bean public TransportClient transportClient() throws UnknownHostException { // 配置集群名称 Settings settings = Settings.builder() .put("cluster.name", "你的ES集群名称") // 开启自动嗅探节点(可选,有助于发现集群内其他节点) .put("client.transport.sniff", true) // 设置连接超时 .put("client.transport.ping_timeout", "30s") .build(); TransportClient client = new PreBuiltTransportClient(settings) .addTransportAddress(new TransportAddress(InetAddress.getByName("ES节点IP"), 9300)); // 如果有多个节点,继续addTransportAddress添加 return client; } @Bean public ElasticsearchOperations elasticsearchOperations() throws UnknownHostException { return new ElasticsearchTemplate(transportClient()); } }
3. 检查ES集群的网络和集群配置
这一步很容易被忽略:
- 修改ES节点的
elasticsearch.yml,确保允许外部连接:network.host: 0.0.0.0 # 允许所有IP访问,生产环境建议设置具体IP transport.tcp.port: 9300 # TransportClient用的是这个端口,不是HTTP的9200 cluster.name: "你的ES集群名称" # 必须和配置类里的cluster.name完全一致 - 重启ES集群,同时检查服务器防火墙是否开放了9300端口,确保Spring Boot应用能访问到这个端口。
4. 排查X-Pack相关配置(如果启用了X-Pack)
如果你的ES集群开启了X-Pack安全认证,还需要在配置里添加账号密码:
Settings settings = Settings.builder() // 其他配置... .put("xpack.security.user", "elastic:你的密码") .build();
如果没有启用X-Pack,确保xpack.security.transport.ssl.enabled设置为false(默认就是false,但最好确认下)。
按照上面的步骤逐一排查,应该就能解决NoNodeAvailableException的问题了。
内容的提问来源于stack exchange,提问作者Martin Čuka




