Как сбалансировать нагрузку службы в .NET - PullRequest
0 голосов
/ 12 октября 2018

Я думаю о создании приложения с использованием сервис-ориентированной архитектуры (SOA).

Эта архитектура не такая сложная и грязная, как решение для микросервисов (я думаю), но я сталкиваюсь с похожими проблемами проектирования.Представьте, что у меня есть сервисы типа ServiceA, которые отправляют работу сервисам типа ServiceB.Я предполагаю, что если я использую очередь, то балансировка нагрузки не будет проблемой (поскольку потребители будут брать то, что они могут обработать, из очереди).Но очереди имеют тенденцию генерировать некоторую плохую асинхронность в коде, которая требует дополнительных усилий для исправления.Итак, я был более склонен использовать HTTP-вызовы между сервисами, используя эффективную и удивительную функцию async/await в C #.Но это порождает проблемы с распределением рабочей нагрузки и обнаружением насыщенных или мертвых сервисов.

Итак, мои вопросы:

  1. Есть ли очередь, поддерживающая какую-то функцию async/awaitи это работает как HTTP-вызов, который возвращает результат там, где он вам нужен, а не в каком-то обратном вызове, где вы не можете продолжить исходный поток выполнения?
  2. Как мне сбалансировать трафик между службами и обнаружить узлы, которыене подходит для новых назначений при использовании HTTP?Я имею в виду, что я, вероятно, могу создать что-то самостоятельно с нуля, но сейчас должен быть какой-то стандартный способ, библиотека или фреймворк.Лучшее, что я нашел в Интернете, было это , но оно создано для микросервисов, поэтому я не уверен, что смогу использовать его без проблем или излишеств.

Обновление: Теперь я обнаружил этот вопрос, который также запрашивает ожидаемые очереди: ожидаемая очередь на основе заданий ... а также обнаружил Kubernetes, Marathon и т. П.

1 Ответ

0 голосов
/ 04 ноября 2018

Что касается вашего первого вопроса, NServiceBus, который является коммерческой платформой для .NET, которая абстрагирует транспорт сообщений и добавляет множество функций поверх них, имеет именно ту функцию, которую вы ищете.На самом деле они называют его « callbacks », и его использование выглядит следующим образом:

Предполагая, что у вас есть Сообщение для отправки в бэкэнд-сервис и Ответ, который вы ожидаете вернуть, вы должны сделать, вServiceA:

var message = new Message();
var response = await endpoint.Request<ResponseMessage>(message);
log.Info($"Callback received with response:{response.Result}");

Где конечная точка - это артефакт NServiceBus, который позволяет отправлять сообщения и получать сообщения.

Что этот простой синтаксис будет делать, это помещать сообщение в очередь и ждать (асинхронно)пока сообщение не будет обработано серверной службой и оно не ответит на него.Ответ - это сообщение типа Response в очереди.

В ServiceB вы должны сделать:

public class Handler : IHandleMessages<Message>
{
  public Task Handle(Message message, IMessageHandlerContext context)
  {
    var responseMessage = new ResponseMessage
    {
        Result = "TheResult"
    };
    return context.Reply(responseMessage);
  }
}

Это позволяет иметь несколько узлов ServiceA, отправляющих сообщения на несколько узлов ServiceB (конкурирующие потребители в одной очереди).NServiceBus заботится о маршрутизации ответа на нужный сервер A для каждого данного сообщения.

Обратите внимание, что это имеет тот недостаток, что, если ServerA отключается во время ожидания ответа, вы никогда не получите ответ.По этой причине этот шаблон не рекомендуется для большинства сценариев.

Что касается вашего вопроса № 2, я бы сказал, что балансировщик нагрузки сделает эту работу.Для более сложных сценариев вы можете посмотреть Service Fabric .

...