Реализация канала публикации-подписки с использованием NServiceBus

Я пытаюсь реализовать канал публикации-подписки с помощью NServiceBus. Согласно книге "Шаблоны интеграции предприятия", канал Pulish-Subscribe описывается следующим образом:

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

Хоуп, Грегор; Вульф, Бобби (2012-03-09). Корпоративные шаблоны интеграции: проектирование, создание и развертывание решений для обмена сообщениями (серия Addison-Wesley Signature (Fowler)) (Kindle Locations 2880-2883). Пирсон Образование. Kindle Edition. "

Образец, содержащий издателя и подписчика, находится по адресу: http://docs.particular.net/samples/step-by-step/. Я построил пример решения для версии 5. Затем я запустил несколько подписчиков в разных окнах командной строки, чтобы посмотреть, как ведет себя система.

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

Я не могу найти никакой информации о том, как настроить NServiceBus как канал публикации-подписки, как определено в цитируемом тексте. Кто-нибудь знает как это сделать? Это не поддерживается?

[Обновление 2 февраля 2016 г.]

Я не переименовал свои конечные точки после копирования подписчиков. Это дало мне желаемое поведение.

2 ответа

Решение

Если вы используете несколько экземпляров одного и того же подписчика, то то, что вы описываете, - это предполагаемая функциональность.

Сценарии

1 издатель, 1 логический подписчик

введите описание изображения здесь

Некоторый процессор публикует событие, и обработчик электронной почты подписывается на это событие. Когда событие используется обработчиком электронной почты, обработчик электронной почты отправит электронное письмо. В этом сценарии есть только один логический подписчик, обработчик электронной почты. Поэтому отправляется только одна копия события.

1 издатель, 2 логических подписчика

введите описание изображения здесь

В следующем сценарии есть два логических подписчика: обработчик счета и обработчик электронной почты. Когда процессор публикует событие, отправляются две копии события. Один для обработчика счетов и один для обработчика электронной почты.

1 издатель, 2 экземпляра 1 логического подписчика

введите описание изображения здесь

В этом сценарии есть только один логический подписчик, хотя на событие подписаны две службы. В этом случае отправляется только одна копия события, и только один из обработчиков электронной почты будет обрабатывать событие. Если оба обработчика электронной почты обработали событие, то вам нужно выполнить N операций для N экземпляров подписчика. Другими словами, два электронных письма будут отправлены вместо одного. Скорее всего, в этом сценарии потребовалось два обработчика электронной почты, поскольку один обработчик не мог справиться с нагрузкой процессора или был необходим для избыточности.

Резюме

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

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

Подписчики должны начать сначала, чтобы иметь возможность отправить сообщение, которое они заинтересованы в подписке на событие. Затем издатель должен загрузиться, успеть обработать сообщения подписки. Когда все подписки сохранены, только тогда вы можете публиковать сообщения. Если вы публикуете сообщения до того, как все подписки будут сохранены, NServiceBus отправит сообщение только тем подписчикам, о которых он уже знает. Через секунду все подписчики могут быть известны, но к тому времени вы уже опубликовали свое сообщение.

При использовании длительного хранения, такого как SQL Server или что-то подобное, подписки будут храниться и сохраняться. Поэтому после перезапуска сервиса сразу все абоненты становятся известны. При хранении в памяти подписки теряются при каждом перезапуске вашего издателя. Поэтому нужно немного подождать, пока все подписки не станут процессами, это дольше.

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

Я сам написал учебник, который также может помочь.

Другие вопросы по тегам