ElasticSearch Java API: NoNodeAvailableException: нет node доступен
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 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?
ИЗМЕНИТЬ
Существует кластер и node часть конфигурации 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
Некоторые предложения:
1 - Используйте порт 9300. [9300-9400] для связи node -to- node, [9200-9300] предназначен для HTTP-трафика.
2. Убедитесь, что версия используемого API Java соответствует версии elasticsearch, запущенной на сервере.
3 - Убедитесь, что имя вашего кластера foxzen
(проверьте файл elasticsearch.yml на сервере).
4 - Удалите put("node.name", "yu")
, вы не присоединяетесь к кластеру как node, так как вы используете TransportClient
, и даже если он появился, ваш сервер node имеет имя yu
, поэтому вы хотел бы хотеть другое имя node в любом случае.
Ответ 2
Вам нужно изменить свой код для использования порта 9300 - правильная строка будет:
Client client = new TransportClient(settings)
.addTransportAddress(new InetSocketTransportAddress("XXX.XXX.XXX.XXX", 9300));
Причина заключается в том, что Java API использует внутренний транспорт, используемый для связи inter node, и по умолчанию используется порт 9300. Порт 9200 по умолчанию используется для интерфейса API REST. Общая проблема для запуска - проверьте этот примерный код здесь в нижней части страницы в разделе Транспортный клиент:
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 как автономный сервер (одиночный node) в докере, программируя с помощью 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
Ответ 4
Я предполагаю, что вы устанавливаете ES-сервер на удаленном хосте? В этом случае вам нужно будет привязать адрес публикации к общедоступному IP-адресу хоста.
В ES-хосте отредактируйте /etc/elasticsearch/elasticsearch.yml
и добавьте его общедоступный IP-адрес после network.publish_host:
# 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)
Ответ 5
Если у вас все еще есть проблемы, даже при использовании порта 9300, и все остальное, кажется, правильно настроено, попробуйте использовать более старую версию elasticsearch.
Я получал ту же ошибку при использовании elasticsearch версии 2.2.0, но как только я вернулась к версии 1.7.5, моя проблема волшебно исчезла. Здесь ссылка на кого-то другого, у кого эта проблема: более старая версия решает проблему
Ответ 6
Для людей с аналогичными проблемами я получил это, потому что не создал cluster.name
в построителе TransportClient
. Добавлено свойство, и все сработало.
Ответ 7
Другая причина может заключаться в том, что ваш клиент Elasticsearch Java является другой версией вашего сервера Elasticsearch.
Версия Elasticearch Java client - это не что иное, как ваша jar-версия elasticsearch в вашей базе кода.
Например: В моем коде это 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 API 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()
не может быть найден. Поэтому добавленный node просто не рассматривается как доступный.