Должен ли я отделить потребителя RabbitMQ от остальной части кода? - PullRequest
0 голосов
/ 03 октября 2019

При реализации, скажем, службы для обработки сообщений электронной почты, следует ли поместить код подписчика RabbitMQ в отдельный процесс от основной программы ? Или это должно быть в общей кодовой базе?

Есть ли недостатки в их объединении?

Мы разрабатываем приложение, ориентированное на микросервис, с .Net Core 3. Мы должны использовать шину обмена сообщениями. позволить многим службам реагировать на некоторые события, опубликованные другими службами. Мы используем RabbitMQ.

Мы уже пытались создать два отдельных приложения, взаимодействующих по HTTP. Один слушает новые сообщения и запускает веб-зацепки на другом. Второй все делает.

Я ожидаю несколько советов о том, как организовать код. Будет ли легче поддерживать общую кодовую базу в будущем? Действительно ли важны издержки синхронизации сетевых запросов?

Ответы [ 3 ]

0 голосов
/ 03 октября 2019

Полагаю, вы говорите о ситуации, когда существует один издатель и много разных приложений (микросервисов), которые обрабатывают сообщения из очереди сообщений. Стоит отметить, что речь идет о приложениях, которые имеют различное бизнес-назначение, но не о многих экземплярах одного и того же приложения.

Я бы порекомендовал придерживаться следующих предложений:

  1. Одна очередьвсегда содержит сообщения одного типа. Другими словами, когда вы десериализуете json, вы должны точно знать, каким классом он должен быть.
  2. В большинстве случаев один микросервис == одно решение VS == один репозиторий.
  3. Вы хотели бы поделитьсякласс для десериализации JSON между микросервисами. Для этого вы можете создать пакет nuget с его интерфейсом. Этот nuget должен содержать классы DTO без какой-либо бизнес-логики. Обычно мы называем этот nuget «* .Contracts».

Главная особенность микросервисной архитектуры - это простота модификации системы, и эти советы должны помочь вам упростить ее с одной стороны и избежать чертовых ошибок. абсолютно неструктурированная система (3-й совет) с другой стороны.

Еще одно уведомление о случае, когда есть один издатель и один потребитель. Это может произойти, если вы хотите обрабатывать данные в фоновом режиме (например, какой-то процесс может занять много времени, но ваш сайт должен немедленно ответить клиенту. В этом случае клиент обычно является веб-пользователем). Для этого случая мы используем одно решение (хранилище) как с издателем, так и с потребителем для упрощения разработки.

0 голосов
/ 04 октября 2019

Мы написали оболочку, которую мы используем в наших микросервисах и приложениях, чтобы абстрагировать детали реализации RabbitMQ. Одной из ключевых вещей, которые он обрабатывает, является отслеживание подписанных событий и связанных с ними обработчиков. Таким образом, приложение может определить / внедрить класс обработчика, и он автоматически вызывается всякий раз, когда приходит соответствующее сообщение.

Для нас мы рассматриваем фактическую реализацию обмена сообщениями как сквозную задачу, поэтому мы упаковываем и используем ее (Пакет Nuget), как и любой другой, это совершенно отдельный проект от всего остального. На самом деле это также общедоступный пакет Nuget, не стесняйтесь играть с ним, если хотите (хотя он недостаточно хорошо документирован).

Вот краткий пример того, как работает наш, чтобы вы могли увидеть уровень интеграции:

В Startup.cs

using MeshIntegrationBus.RabbitMQ;

public class Startup
{
   public RabbitMqConfig GetRabbitMqConfig()
   {
      ExchangeType exchangeType = (ExchangeType)Enum.Parse(typeof(ExchangeType),
         Configuration["RabbitMQ:IntegrationEventExchangeType"], true);

      var rabbitMqConfig = new RabbitMqConfig
      {
         ExchangeName = Configuration["RabbitMQ:IntegrationEventExchangeName"],
         ExchangeType = exchangeType,
         HostName = Configuration["RabbitMQ:HostName"],
         VirtualHost = Configuration["RabbitMQ:VirtualHost"],
         UserName = Configuration["RabbitMQ:UserName"],
         Password = Configuration["RabbitMQ:Password"],
         ClientProviderName = Configuration["RabbitMQ:ClientProviderName"],
         Port = Convert.ToInt32(Configuration["RabbitMQ:Port"])
       }
      return rabbitMqConfig
   }

   public void ConfigureServices(IServicecollection services)
   {
      services.Add.... // All your stuff

      // If this service will also publish events, add that Service as well (scoped!)
      services.AddScoped<IMeshEventPublisher, RabbitMqEventPublisher>(s =>
         new RabbitMqEventPublisher(rabbitConfig));

      // Since this service will be a singleton, wait until the end to actually add it
      // to the servicecollection - otherwise BuildServiceProvider would duplicate it
      RabbitMqListener rabbitMqListener = new RabbitMqListener(rabbitConfig, 
         services.BuildServiceProvider());

      var nodeEventSubs = Configuration.GetSection(
         $"RabbitMQ:SubscribedEventIds:ServiceA").Get<string[]>();

      // Attach our list of events to a handler
      // Handler must implement IMeshEventProcessor and does have
      // access to the IServiceProvider so can use DI
      rabbitMqListener.Subscribe<ServiceAEventProcessor>(nodeEventSubs);

      services.AddSingleton(rabbitMqListener);
   }
}

Вот и все, что нужно сделать. Вы можете добавить несколько обработчиков для каждого подписанного события и / или повторно использовать один и тот же обработчик (и) для нескольких событий. Он оказался довольно гибким и надежным - мы используем его уже пару лет - и его достаточно легко менять / обновлять по мере необходимости и позволять отдельным службам вносить изменения, когда они хотят / нуждаются.

0 голосов
/ 03 октября 2019

Недавно я разработал и разработал программное обеспечение, которое взаимодействует с другими компонентами через AMQP, внедренное RabbitMQ.

Как мой вопрос дизайна, я написал повторно используемый класс обслуживания, который вызывается другими классами обслуживания. Это происходит на уровне обслуживания или, можно сказать, на бизнес-уровне.

Но, как вы спросили, есть ли несколько приложений, и все ли они должны реализовывать клиент RabbitMQ, я бы создал библиотеку / модуль / пакет, который можно легкоимпортируется в приложения и настраивается.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...