У меня есть веб-сервис, который использует Rebus в качестве служебной шины. Ребус настроен так, как описано в этом посте. Веб-служба сбалансирована по нагрузке с кластером из двух серверов.
Эти сервисы предназначены для производственной среды, и каждая производственная машина отправляет команды для сохранения произведенных объемов и/или обновления своего состояния.
В BL я смоделировал совокупный корень для каждой машины, и он выполняет команды, выдаваемые настоящая машина. Чтобы сохранить правильный статус, Aggregate должен получать команды в той же последовательности, в которой они были отправлены, и, поскольку для этой машины нет параллелизма, в том же порядке они сохраняются на шине.
Например: машина XX отправляет команду 'добавить новую деталь в готовом виде', а затем команду 'установить остановку для технического обслуживания'. Выполняя эти команды в последовательности, вы должны иметь Aggregate XX в состоянии 'Stop', но при наличии нескольких серверных/рабочих ролей обе команды могут выполняться одновременно в одной и той же версии Совокупность. Это означает, что в зависимости от того, кто первым сохранит агрегат, у меня может быть агрегат XX с состоянием "Остановить" или "Производить детали"... это не одно и то же. .
Я ввел служебную шину, чтобы добавить масштабирование в виде количества масштабов машины и устойчивости (в случае сбоя сервера у меня будет только замедление обработки команд).
На самом деле я использую имя агрегата, например "topic" или "destinationAddress" с IAdvancedApi. , поэтому имя агрегата сохраняется в получателе транспорта. Затем я создал собственный класс транспорта, который:
1. не удаляет сообщения в процессе обработки, а переводит их в состояние InProgress.
2. для извлечения сообщений выбираются только те, которые находятся в получателе, у которого нет InProgress.
Я блуждаю: это лучший способ гарантировать, что шина выполняет команды для агрегата в той же последовательности, в которой они прибыли?