Service Fabric ServicePartitionResolver.ResolveAsync, по-видимому, игнорирует балансировщик нагрузки. - PullRequest
0 голосов
/ 14 июня 2019

У меня есть служба без сохранения состояния, которая выступает в качестве шлюза для всех запросов в мой 5-узловый кластер

Эта служба перенаправляет запросы на службы в кластере

    protected virtual async Task<ResolvedServicePartition> FindPartitionAsync(long key = 0)
    {
        var resolver = ServicePartitionResolver.GetDefault();
        var result = await resolver.ResolveAsync(FullServiceName, ServicePartitionKey.Singleton, CancellationToken.None).ConfigureAwait(false);
        return result;
    }

    private async Task<string> EstablishProxyUrlAsync(string method, long key = 0)
    {
        var partition = await FindPartitionAsync(key).ConfigureAwait(false);

        if (key != 0)
        {
            Log.Information($"{this.GetType().Name} method {method} request resolved by partition {partition.Info.Id}");
        }

        var endpoints = JObject.Parse(partition.GetEndpoint().Address)["Endpoints"];
        var address = endpoints[""].ToString().TrimEnd('/');

        var proxyUrl = $"{address}/api/{Area}/{method}";

        return proxyUrl;
    }

У меня есть подозрение, чтоесли у меня есть служба - TestService, которая находится на всех 5 узлах моего кластера, приведенный выше код игнорирует балансировщик нагрузки, поэтому запрос просто переходит к экземпляру на узле, который принял запрос

Есть ли способчтобы это исправить?

Нужно ли мне тогда реализовать свой собственный балансировщик нагрузки?Все вызовы извне поступают в шлюз, так как это кажется рекомендуемым способом, т. Е. Единой точкой входа.Однако создается впечатление, что теперь эта концепция будет замедлять работу и увеличивать нагрузку на конкретный узел, поскольку не существует балансировщика нагрузки для выбора лучшего узла.Например, если у меня есть метод шлюза GetCars, который вызывает GetCars для службы без сохранения состояния, которая находится на всех 5 узлах, мне нужен способ балансировки нагрузки для одного из этих узлов, а не для всех запросов на локальный экземпляр

Пол

1 Ответ

1 голос
/ 15 июня 2019

Я ожидаю, что разрешенный адрес конечной точки будет содержать внутренний IP-адрес узла, на котором размещена первичная реплика TestService, и порта, который использует его прослушиватель.

  • Для службы с отслеживанием состояния это может быть только одна конечная точка.

  • Для службы Singleton вы получите кэшированный результат из ServicePartitionResolver.

Вы можете принудительно выполнить обновление, используя resolver.ResolveAsync() с перегрузкой, которая принимает более раннюю ResolvedServicePartition.

Кроме того, поскольку внутренние вызовы не выполняются через Интернет, вызов не будет проходить через (Azure) балансировщик нагрузки.

Добавлена ​​дополнительная информация:

Вероятно, вы запустите шлюз на всех узлах. Если нет, убедитесь, что вы делаете это. Поскольку у каждого шлюза есть свой собственный преобразователь, который разрешается в «случайный» экземпляр, вы должны увидеть, что нагрузка будет затем автоматически распределена по нисходящим службам.

P.S. взгляните на Traefik , это может помочь вам решить эту проблему без необходимости создания надежного обратного прокси.

подробнее здесь и здесь

...