2014-05-07 25 views
20
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(); 
} 

我從我的計算機上訪問服務器節點ElasticSearch的Java API:NoNodeAvailableException:無

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的出現錯誤?

EDIT

有一種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 

回答

29

一些建議羣集和節點部的配置:

1 - 使用端口9300。[9300-9400]爲節點 - 節點間通信,[9200-9300]用於HTTP流量。

2 - 確保您使用的Java API版本與服務器上運行的elasticsearch版本相匹配。

3 - 確保羣集的名稱是foxzen(檢查服務器上的elasticsearch.yml)。

4 - 刪除put("node.name", "yu"),你是不是加入集羣的節點,因爲你使用的是TransportClient,即使你是它出現在您的服務器節點被命名爲yu所以你會在任何情況下,希望有一個不同的節點名稱。

+0

ElasticSearch Java API版本爲0.19.9。我不知道如何檢查ElasticSearch服務器的版本 – Joe

+0

您可以檢查服務器上的安裝目錄,只需查看安裝目錄lib文件夾並查看elasticsearch jar的版本。可能有一種方法可以通過curl來獲取版本,但是我無法將它想到我的頭頂(如果我可以的話,我不會相信它能夠在舊版本上工作)。 – hudsonb

+0

您的服務器正在運行Elasticsearch 1.1.0版(它是'「number」:「1.1.0」'條目),您在問題中發佈的curl請求的響應中。 –

10

你需要改變你的代碼,使用端口9300 - 正確的路線是:

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

的原因是,Java API的是使用用於節點間通信的內部運輸,其默認值爲端口9300 。端口9200是REST API接口的默認端口。常見的問題碰上 - 在這裏檢查此示例代碼實現頁面的底部,下的運輸客戶:

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(); 
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上的經驗)

+0

network.host:xxx.xxx.xxx.xxx工作對我來說,TX! – cnmuc

+0

謝謝!我在我的yml文件中有錯誤的配置。 network.host:屬性被設置爲0.0.0.0。 將它更改爲127.0.0.1就像魅力一樣工作 –

0

如果您仍然遇到問題,即使使用端口9300,並且其他配置似乎都已正確配置,請嘗試使用舊版本的elasticsearch。

我在使用elasticsearch版本2.2.0時遇到了同樣的錯誤,但只要我回滾到版本1.7.5,我的問題就神奇地消失了。這是一個鏈接到其他人有這個問題:older version solves problem

0

對於有類似問題的人,我收到這個,因爲我沒有在TransportClient建設者中設置cluster.name。增加了財產和一切工作。

2

我也遇到過這個錯誤。我使用ElasticSearch 2.4.1作爲Docker中的獨立服務器(單節點),使用Grails 3/spring-data-elasticsearch進行編程。我的修復程序將client.transport.sniff設置爲false。這是我核心的conf:

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

+1

參考ES 2.4文檔(https://www.elastic.co/guide/en/elasticsearch/client/java-api/2.4/transport-client.html),在我看來,「client.transport.sniff」默認是禁用的 - 作爲超時5秒。所以這裏唯一的實際修改是'cluster-name'和'ignore_cluster_name'。我相信這個配置對原始問題NoNodeAvailableException沒有影響(正面或負面)。 – Beccari

+0

@Beccari 你是對的。我測試代碼,即使我註釋掉'spring.data.elasticsearch.properties',我的代碼仍然可以工作。使用屬性的elasticsearch源代碼是[here](https://github.com/elastic/elasticsearch/blob/2.4/core/src/main/java/org/elasticsearch/client/transport/TransportClientNodesService.java#L123) 我犯了一個和Dan Barzilay一樣的錯誤:將「client.transport.sniff」設置爲true,然後得到了'NoNodeAvailableException'。 這與原始問題不一樣。但也許提醒別人。 – btpka3

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 

正如你所看到的,我已經下載了最新版本的彈性服務器5.2.2但忘了更新ES Java API客戶端版本2.4.0 https://www.elastic.co/guide/en/elasticsearch/client/java-api/current/client.html

0

另一種解決方案可能是將io.netty.netty-all包含到項目中顯式依賴關係。

addTransportAddresses方法nodesSampler.sample()正在執行,並且正在檢查添加的地址的可用性。 在我的情況下try-catch塊燕子ConnectTransportException,因爲找不到方法io.netty.channel.DefaultChannelId.newInstance()。所以添加的節點不被視爲可用。