Нужна ли мне служебная шина для простой асинхронной обработки команд?

StackOverflow https://stackoverflow.com//questions/11696122

Вопрос

Моя система использует шаблон команды с отдельными обработчиками.Мои команды выполняются в CommandService, который в настоящее время обрабатывает все команды в процессе.

У меня есть определенные команды, которые выполняют хотя бы одну из этих операций, которые являются медленными операциями:

  1. Отправляет электронное письмо
  2. Создает PDF-файл
  3. Отправляет факс
  4. Взаимодействует со сторонними веб-сервисами

Я хочу, чтобы все эти команды обрабатывались вне процесса, чтобы пользовательский интерфейс был более быстрым.

Должен ли я использовать шину обмена сообщениями только для этих команд или мне следует вызвать внутрипроцессный обработчик команд? BeginInvoke()?

Изменить – дополнительная информация

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

Принимая во внимание всю ситуацию, я думаю, что я собираюсь пойти с BeginInvoke() на данный момент по нескольким причинам:

  1. Необходимо будет коснуться всех взаимодействий пользовательского интерфейса, чтобы убедиться, что они ведут себя так, как будто команда выполнена успешно.Напоминание о том, что «вам необходимо отправить этот документ», находится в нескольких местах пользовательского интерфейса, и после отправки отчета оно полностью обновляет страницу.
  2. Сейчас середина напряженного сезона у моих клиентов (более 50% годового бизнеса они выполняют летом), поэтому мне не кажется разумным в настоящее время вводить совершенно новую часть инфраструктуры, с администрированием которой я не знаком. .

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

Это было полезно?

Решение

Оба решения имеют свои плюсы и минусы.

  • BeginInvoke — чрезвычайно простое решение, и его семантика такая же, как прямой вызов обработчика по команде.Но это решение зависит от инфраструктуры потоков:максимальное количество потоков, замороженный поток из-за одновременного доступа к ресурсам ввода-вывода и т. д.
  • MessageBus — очень гибкое и мощное решение, позволяющее контролировать каждый аспект процесса обработки команд.Но это вводит в ваше приложение еще один уровень абстракции, что было бы излишней инженерией в том случае, если чем проще, тем лучше.

Я бы рекомендовал оценить требования к загрузке вашей системы, количество этих фоновых задач, коэффициент роста и т. д. и в зависимости от этого принять решение.

Но, по моему личному мнению, внедрение автобусного решения подходит в 80% случаев.Вы можете представить простую реализацию шины, которую при необходимости можно будет расширить на следующих итерациях.

Другие советы

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

Шина сообщений сможет откатить эту вторую транзакцию в очередь, чтобы при повторном запуске сервера он снова отправлял электронное письмо.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top