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.端口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();
我也遇到了这个错误。 我使用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()
。 因此添加的节点不被视为可用。