You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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

火山引擎 最新活动