Вы думаете о событиях, как будто они реализованы в пользовательском интерфейсе Winforms, где издатель отправляет событие непосредственно подписчику.Это не то, как события работают в архитектуре EDA.Слово «событие» приобрело совершенно новое значение.
Прежде чем мы начнем, вы смешиваете идеи сообщения и события, когда их действительно необходимо разделить.Сообщение - это запрос на какое-либо действие, а событие - это уведомление о том, что что-то уже произошло.Важным отличием этого обсуждения является то, что издатель сообщения предполагает, что один или несколько других процессов получат и обработают сообщение.Если сообщение чем-то не обработано, произойдут последующие ошибки.Событие не имеет такого предположения и может оставаться непрочитанным, не оказывая негативного влияния на что-либо.Другое отличие состоит в том, что после обработки сообщений они обычно выбрасываются, тогда как события хранятся в течение длительного периода (дней или недель).
С учетом этого служба «X», о которой вы говорите, уже существует(пожалуйста, не создавайте один) и является неотъемлемой частью процесса - он называется шиной.Есть 2 типа автобусов;шина сообщений (например, RabbitMQ, MSMQ, ZeroMQ и т. д.) или шина событий (Kafka, Kinesis или Azure Event Hub).В любом случае издатель помещает сообщение в шину, а подписчики получают его из шины.Вы можете реализовать серверы шин в виде нескольких физических шин, но когда представляете, что все они представляют собой одну и ту же логическую шину.
Ключевой момент, который сбивает вас с толку, и это тонкое различие, это думать, что сообщениеУ шины есть бизнес-логика, указывающая, куда отправляются сообщения.Бизнес-логика того, кто получает какое сообщение, определяется подписчиками - шина сообщений является просто местом хранения сообщений, ожидающих получения.
В вашем примере A публикует событие на шине с сообщениемТип «МТ1».B и C оба сообщают шине, что они заинтересованы в событиях типа «MT1».Когда шина получает запрос от B и C на уведомление о сообщениях «MT1», шина создает очередь для B и очередь для C. Когда A публикует сообщение, шина помещает копию в «B-MT1»очередь и копия в очереди «C-MT1».Обратите внимание, что шина не знает, почему B и C хотят получать эти сообщения, только что они подписаны.
Эти сообщения остаются там до тех пор, пока не будут обработаны их соответствующими подписчиками (процессы могут опрашивать или шина можетнажмите на сообщения, но основная идея заключается в том, что сообщения хранятся до обработки).После обработки сообщения выбрасываются.
Для связи C с D, D подпишется на сообщения типа «MT2», а C публикует их на шине.
Ответ Константина, приведенный выше, указывает на то, что это единственная точка отказа, но ею можно управлять с помощью стандартной сетевой архитектуры, такой как отказоустойчивые серверы, локальное сохранение сообщений, подтверждения сообщений и т. Д.
ОдинВас беспокоит то, что с тысячами подписок становится трудно следовать по пути, и вы правы.Это неотъемлемая сторона EDA, и вы ничего не можете с этим поделать.Возможная согласованность - это также то, о чем бизнес будет жаловаться, но это часть зверя и на самом деле хорошая вещь с технической точки зрения, поскольку она обеспечивает большую масштабируемость.Самая большая проблема, которую я обнаружил при использовании термина «Возможная согласованность», заключается в том, что компания считает, что это означает часы или дни, а не секунды.
Кстати, все это обсуждение предполагает, что издатели сообщений и подписчики - это разные приложения.Все те же идеи могут быть применены в одном и том же адресном пространстве, только с другой шиной.Если вы магазин .net, посмотрите на Mediatr.Для других технических стеков есть похожие решения, о которых, я уверен, Google знает.