有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

ElasticSearch Java API:NoNodeAvailableException:无可用节点

public static void main(String[] args) throws IOException {
    Settings settings = ImmutableSettings.settingsBuilder()
            .put("cluster.name", "foxzen")
            .put("node.name", "yu").build();
    Client client = new TransportClient(settings)
            .addTransportAddress(new InetSocketTransportAddress("XXX.XXX.XXX.XXX", 9200));
            // XXX is my server's ip address
    IndexResponse response = client.prepareIndex("twitter", "tweet")
            .setSource(XContentFactory.jsonBuilder()
                    .startObject()
                    .field("productId", "1")
                    .field("productName", "XXX").endObject()).execute().actionGet();
    System.out.println(response.getIndex());
    System.out.println(response.getType());
    System.out.println(response.getVersion());
    client.close();
}

我从我的计算机访问服务器

curl -get http://XXX.XXX.XXX.XXX:9200/

明白了吗

{
    "status" : 200,
    "name" : "yu",
    "version" : {
        "number" : "1.1.0",
        "build_hash" : "2181e113dea80b4a9e31e58e9686658a2d46e363",
        "build_timestamp" : "2014-03-25T15:59:51Z",
        "build_snapshot" : false,
        "lucene_version" : "4.7"
    },
    "tagline" : "You Know, for Search"
}

为什么使用JavaAPI会出现错误

编辑

elasticsearch.yml的集群和节点部分配置

################################### Cluster ###################################

# Cluster name identifies your cluster for auto-discovery. If you're running
# multiple clusters on the same network, make sure you're using unique names.
#
cluster.name: foxzen


#################################### Node #####################################

# Node names are generated dynamically on startup, so you're relieved
# from configuring them manually. You can tie this node to a specific name:
#
node.name: yu

共 (6) 个答案

  1. # 1 楼答案

    一些建议:

    1-使用端口9300。[9300-9400]用于节点间通信,[9200-9300]用于HTTP通信

    2-确保您使用的Java API版本与服务器上运行的elasticsearch版本匹配

    3-确保集群的名称为foxzen(检查服务器上的elasticsearch.yml)

    4-删除put("node.name", "yu"),您没有作为节点加入集群,因为您使用的是TransportClient,即使是这样,您的服务器节点似乎命名为yu,因此您在任何情况下都需要不同的节点名称

  2. # 2 楼答案

    我假设您正在远程主机上设置ES服务器?在这种情况下,您需要将发布地址绑定到主机的公共IP地址

    在ES主机中,编辑/etc/elasticsearch/elasticsearch.yml并在网络后添加其公共IP。发布主机:

    # Set the address other nodes will use to communicate with this node. If not
    # set, it is automatically derived. It must point to an actual IP address.
    #
    network.publish_host: 192.168.0.1
    

    在您的代码中,在端口9300上连接到此主机。请注意,您需要的是IP而不是域名(至少根据我在Amazon EC2上的经验)

  3. # 3 楼答案

    我也遇到了这个错误。我使用ElasticSearch 2.4.1作为docker中的独立服务器(单节点),使用Grails 3/spring数据ElasticSearch进行编程。我的解决方案是将client.transport.sniff设置为false。以下是我的核心配置:

    应用程序。yml

    spring.data.elasticsearch:
        cluster-name: "my-es"
        cluster-nodes: "localhost:9300"
        properties:
            "client.transport.ignore_cluster_name": true
            "client.transport.nodes_sampler_interval": "5s"
            "client.transport.ping_timeout": "5s"
            "client.transport.sniff": false      # XXX : notice here
        repositories.enabled: false
    

    this

  4. # 4 楼答案

    对于有类似问题的人,我收到这个消息是因为我没有在TransportClient生成器中设置cluster.name。添加了属性,一切正常

  5. # 5 楼答案

    如果您仍然有问题,即使在使用端口9300时,并且其他所有配置似乎都正确,请尝试使用旧版本的elasticsearch

    我在使用elasticsearch 2.2.0版时也遇到了同样的错误,但当我回到1.7.5版时,我的问题就神奇地消失了。这里有一个指向有此问题的其他人的链接:older version solves problem

  6. # 6 楼答案

    您需要更改代码以使用端口9300-正确的行为:

     Client client = new TransportClient(settings)
                .addTransportAddress(new InetSocketTransportAddress("XXX.XXX.XXX.XXX", 9300));
    

    原因是Java API使用用于节点间通信的内部传输,默认为端口9300。端口9200是REST API接口的默认端口。遇到的常见问题-请在页面底部的Transport Client(传输客户端)下检查此示例代码:

    http://www.elasticsearch.org/guide/en/elasticsearch/client/java-api/current/client.html

    // on startup
    
    Client client = new TransportClient()
            .addTransportAddress(new InetSocketTransportAddress("host1", 9300))
            .addTransportAddress(new InetSocketTransportAddress("host2", 9300));
    
    // on shutdown
    
    client.close();