Подтвердить что ты не робот

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
4b9b3361

Ответ 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 просто не рассматривается как доступный.