Может ли конечная точка NServiceBus подписаться на несколько издателей одного и того же сообщения? - PullRequest
7 голосов
/ 26 января 2012

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

public interface IPositionMessage : IMessage
{
   string UnitName { get; set; }
   double Latitude { get; set; }
   double Longitude { get; set; }
}

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

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

Существует ли какой-либо метод, позволяющий подписчикам подписываться на одно и то же сообщение от нескольких издателей?

Ответы [ 2 ]

12 голосов
/ 28 января 2012

Это одна из тех «ям успеха» в SOA, из-за которых Уди пытается вам очень трудно убежать.

Основная двойственность такова:

  • Команды должны отправляться многими клиентами и получаться из одного авторитетного источника.
  • События должны публиковаться из одного авторитетного источника и получать многие клиенты.

Но этот единственный авторитетный источник является ЛОГИЧЕСКИМ авторитетным источником. Важным моментом является то, что если меня интересуют все данные IPositionMessage, должен быть только один логический пункт (queuename @ servername), куда я отправляю свои запросы на подписку.

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

Ключ заключается в том, что все ваши физические процессоры должны совместно использовать одно хранилище подписки. Фактически, вы можете захотеть, чтобы одна физическая конечная точка обрабатывала только запросы на подписку и вообще не обрабатывала. Он просто получает запросы на подписку (QueueX @ ServerY заинтересован в IPositionMessage) и обновляет хранилище подписки.

Затем каждый процессор, связанный с тем же хранилищем подписки, отправляется на публикацию IPositionMessage и обнаруживает, что QueueX @ ServerY заинтересован, и отправляет копию события в это местоположение.

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

1 голос
/ 27 января 2012

Хотя можно подписаться более чем на одного издателя (это можно настроить в <unicastBusConifg />), я согласен с группой пользователей в том, что это должно стать логической отправкой, а не публикацией.

Я не совсем понимаю, почему я так думаю.

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