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" } 

为什么使用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 

一些建议:

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

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

3 – 确保群集名称为foxzen (检查服务器上的foxzen )。

4 – 删除put("node.name", "yu") ,因为您使用的是TransportClient ,所以您没有将集群作为节点加入,即使您出现了,您的服务器节点也会被命名为yu因此您可能需要在任何情况下都是不同的节点名称。

您需要更改代码以使用端口9300 – 正确的行将是:

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

原因是Java API使用用于节点间通信的内部传输,默认为端口9300.端口92​​00是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(); 

我也遇到了这个错误。 我使用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 

看到这个

我假设您在远程主机上设置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上的经验)

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

我在使用elasticsearch 2.2.0时遇到了同样的错误,但是当我回滚到1.7.5版时,我的问题神奇地消失了。 这是与其他人有这个问题的链接: 旧版本解决了问题

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

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

Elasticsearch Java客户端版本只是代码库中的弹性搜索 jar版本。

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

要validationElasticsearch服务器版本,

 $ /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 /电流/ client.html

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

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