ElasticSearch Java API:NoNodeAvailableException:没有可用的节点

时间:2014-05-07 14:31:49

标签: java elasticsearch

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

8 个答案:

答案 0 :(得分:32)

一些建议:

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

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

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

4 - 删除put("node.name", "yu"),因为您正在使用TransportClient,所以您不会将群集作为节点加入群集,即使您出现了,您的服务器节点也会被命名为{{1}所以在任何情况下你都想要一个不同的节点名。

答案 1 :(得分:10)

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

答案 2 :(得分: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

答案 3 :(得分:1)

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

答案 4 :(得分:0)

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

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

答案 5 :(得分:0)

对于有类似问题的人,我收到了这个,因为我没有在IMonad构建器中设置type f ~> g = forall x. f x -> g x class IMonad m where ireturn :: a ~> m a (=<?) :: (a ~> m b) -> (m a ~> m b) 。添加了属性,一切正常。

答案 6 :(得分:0)

其他原因可能是,您的 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

答案 7 :(得分:0)

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

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