Избегание ошибки ElasticSearch 503 Сервер недоступен: использование WaitForStatus - PullRequest
0 голосов
/ 23 января 2020

Когда я запускаю свою программу, я запускаю сервис ElasticSearch и проверяем, существует ли индекс и есть ли какие-либо документы , допустим, я просто запустил службу ES, и у меня есть эти две функции:

public ElasticClient getElasticSearchClient()
{
    ConnectionSettings connectionSettings = new Nest.ConnectionSettings(new Uri("http://localhost:9200"))
                                                    .DefaultIndex("myindex")
                                                    .DisableDirectStreaming();
    ElasticClient client = new ElasticClient(connectionSettings);
    //var health = client.Cluster.Health("myindex", a => (a.WaitForStatus(WaitForStatus.Yellow)).Timeout(50));
    return client;
}

public void checkElasticsearchIndex()
{
    var client = getElasticSearchClient();

    var health = this.client.Cluster.Health("myindex", a => (a.WaitForStatus(WaitForStatus.Yellow)));

    CountResponse count = client.Count<myobject>();

    if (!client.Indices.Exists("myindex").IsValid || count.Count == 0)
    {
        BulkWriteAllToIndexES(client);
    }
}

Внутри функции checkElasticsearchIndex,

  1. Сбой операции подсчета со следующим сообщением об ошибке:

    OriginalException: Elasticsearch. Net .ElasticsearchClientException: удаленный сервер возвратил ошибку: (503) сервер недоступен. Вызов: код состояния 503 из: GET / myindex / _count. ServerError: Тип: search_phase_execution_exception Причина: «все осколки не удалось» ---> Система. Net .WebException: удаленный сервер возвратил ошибку: (503) Сервер недоступен.

  2. Сбой работоспособности также:

    OriginalException: Elasticsearch. Net .ElasticsearchClientException: Невозможно подключиться к удаленному серверу. Вызов: код состояния неизвестен из: GET / _cluster / health / myindex? Wait_for_status = yellow ---> System. Net .WebException: невозможно подключиться к удаленному серверу ---> System. Net .Sockets.SocketException : Невозможно установить соединение, потому что целевая машина активно отказалась от него работа.

    Мой вопрос: есть ли способ подождать, пока клиент / кластер / узлы не будут готовы и не получить никаких исключений?

1 Ответ

2 голосов
/ 24 января 2020

Похоже, вы запускаете процесс Elasticsearch одновременно с запуском вашей программы, но Elasticsearch требует больше времени, чем ваша программа, чтобы быть готовой.

В этом случае вас может заинтересовать использование тех же абстракций , которые клиент NET использует для интеграционных тестов с Elasticsearch. Абстракции читают выходные данные процесса Elasticsearch, чтобы узнать, когда он будет готов, и блокировать, пока это не произойдет. Они доступны в фиде пакетов CI AppVeyor (с планами выпустить их в Nuget в будущем).

Есть несколько примеров того, как ускорить кластер с помощью абстракции . Для одного узла это будет что-то вроде

using System;
using Elastic.Managed.Configuration;
using Elastic.Managed.ConsoleWriters;
using Elastic.Managed.FileSystem;

namespace Elastic.Managed.Example
{
    class Program
    {
        static void Main(string[] args)
        {
            var version = "7.5.1";
            var esHome = Environment.ExpandEnvironmentVariables($@"%LOCALAPPDATA%\ElasticManaged\{version}\elasticsearch-{version}");

            using (var node = new ElasticsearchNode(version, esHome))
            {
                node.SubscribeLines(new LineHighlightWriter());
                if (!node.WaitForStarted(TimeSpan.FromMinutes(2))) throw new Exception();

                // do your work here
            }
        }
    }
}

Это предполагает, что zip-архив Elasticsearch 7.5.1 уже загружен и существует в %LOCALAPPDATA%\ElasticManaged\7.5.1\elasticsearch-7.5.1. Есть более сложные примеры того, как интегрировать это в тесты с xUnit.

Вы можете использовать EphemeralCluster компоненты для загрузки, настройки и запуска Elasticsearch

var plugins = new ElasticsearchPlugins(ElasticsearchPlugin.RepositoryAzure, ElasticsearchPlugin.IngestAttachment);
var config = new EphemeralClusterConfiguration("7.5.1", ClusterFeatures.XPack, plugins, numberOfNodes: 1);
using (var cluster = new EphemeralCluster(config))
{
    cluster.Start();

    var nodes = cluster.NodesUris();
    var connectionPool = new StaticConnectionPool(nodes);
    var settings = new ConnectionSettings(connectionPool).EnableDebugMode();
    var client = new ElasticClient(settings);

    Console.Write(client.CatPlugins().DebugInformation);
}
...