【问题标题】:ElasticSearch Java API:NoNodeAvailableException: No node availableElasticSearch Java API:NoNodeAvailableException:没有可用的节点
【发布时间】:2014-06-24 14:24:56
【问题描述】:
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"
}

为什么使用 Java API 会出错?

编辑

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

【问题讨论】:

    标签: java elasticsearch


    【解决方案1】:

    一些建议:

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

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

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

    4 - 删除put("node.name", "yu"),因为您使用的是TransportClient,所以您不会作为节点加入集群,即使您的服务器节点似乎命名为yu,所以您需要一个不同的任何情况下的节点名称。

    【讨论】:

    • ElasticSearch Java API 版本是 0.19.9。我不知道如何查看 ElasticSearch 服务器的版本
    • 你能检查一下服务器上的安装目录吗,只需查看安装目录的lib文件夹,看看elasticsearch jar是什么版本。可能有一种方法可以通过 curl 获取版本,但我无法想到它(如果可以的话,我也不相信它可以在旧版本上工作)。
    • 在您在问题中发布的 curl 请求的响应中,您的服务器正在运行 Elasticsearch 版本 1.1.0(它是 "number": "1.1.0" 条目)。
    • 猜我是盲人。根据我的第一个建议升级您的 Java 客户端以使用 elasticsearch-1.1.0.jar。
    • 将 jar 版本更新为与服务器版本相同的版本对我有用
    【解决方案2】:

    您需要更改代码以使用端口 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();
    

    【讨论】:

      【解决方案3】:

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

      application.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

      【讨论】:

      • 参考 ES 2.4 文档 (elastic.co/guide/en/elasticsearch/client/java-api/2.4/…) ,在我看来“client.transport.sniff”默认是禁用的 - 因为超时 5s。所以这里唯一的实际修改是cluster-nameignore_cluster_name。我相信这个配置对原来的问题NoNodeAvailableException没有影响(正面或负面)。
      • @Beccari 你是对的。我测试了代码,即使我注释掉了spring.data.elasticsearch.properties,我的代码仍然有效。使用propertis的elasticsearch源代码是here。我犯了和Dan Barzilay一样的错误:将“client.transport.sniff”设置为true,然后得到NoNodeAvailableException。这与原始问题不同。但也许是对其他人的提醒。
      【解决方案4】:

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

      在您的 ES 主机中编辑 /etc/elasticsearch/elasticsearch.yml 并在 network.publish_host 之后添加其公共 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 上的经验)

      【讨论】:

      • 谢谢!我的 yml 文件中的配置错误。 network.host:属性设置为 0.0.0.0。将其更改为 127.0.0.1 就像一个魅力
      【解决方案5】:

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

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

      【讨论】:

        【解决方案6】:

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

        【讨论】:

          【解决方案7】:

          其他原因可能是,您的 Elasticsearch Java 客户端与您的 Elasticsearch 服务器版本不同。

          Elasticsearch Java 客户端版本只不过是代码库中的 elasticsearch jar 版本。

          例如:在我的代码中是 elasticsearch-2.4.0.jar

          要验证 Elasticsearch 服务器版本,

          $ /Users/kkolipaka/elasticsearch/bin/elasticsearch -version
          Version: 5.2.2, Build: f9d9b74/2017-02-24T17:26:45.835Z, JVM: 1.8.0_111
          

          如您所见,我下载了最新版本的 Elastic server 5.2.2 但忘记更新 ES Java API 客户端版本 2.4.0 https://www.elastic.co/guide/en/elasticsearch/client/java-api/current/client.html

          【讨论】:

            【解决方案8】:

            另一种解决方案可能是将io.netty.netty-all 明确包含到项目依赖项中。

            addTransportAddresses 上,正在执行nodesSampler.sample() 方法,并且正在检查添加的地址是否可用。 在我的情况下,try-catch 块吞噬了ConnectTransportException,因为找不到方法io.netty.channel.DefaultChannelId.newInstance()。所以添加的节点不被视为可用。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-11-12
              • 2015-09-24
              • 1970-01-01
              • 1970-01-01
              • 2014-09-23
              • 1970-01-01
              相关资源
              最近更新 更多