В архитектуре, управляемой событиями, нормально ли, чтобы все службы отправляли свое событие компоненту, который перенаправляет его в соответствующую службу? - PullRequest
0 голосов
/ 30 сентября 2018

Допустим, я хочу установить и управляемую событиями архитектуру со службами A - D, где события распространяются следующим образом

            A
          /   \
         B     C
              /
             D

Другими словами,

(1) A публикует событие

(2) Подписчики B и C получают A событие

(3) C публикует событие

(4) Подписчик D событие получения C

Одним из способов является предоставление службам B и C прямого прослушивания очереди, в которую A отправляет сообщения.Но проблема, которую я вижу с этим, является обслуживанием.Как только система усложняется тысячами подписок, становится трудно понять, как распространяются обновления.

Решение, которое я предлагаю для этой проблемы, состоит в том, чтобы иметь другой сервис X, который знает дерево на первом изображении и отвечает за направление распространения событий в соответствии с деревом.Каждый сервис публикует свое событие на X и публикует это событие для сервисов прослушивания.Так что это своего рода посредник вроде

     A
     |
     X
    / \
   B   C
       |
       X
       |
       D

Это также облегчает отслеживание распространения событий.

Есть ли какие-либо недостатки в этом (кроме дополнительных затрат, связанных с вдвое большей передачей сообщений)?

Ответы [ 3 ]

0 голосов
/ 01 октября 2018

Вы думаете о событиях, как будто они реализованы в пользовательском интерфейсе 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 знает.

0 голосов
/ 02 октября 2018

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

Большинство платформ / библиотек обмена сообщениями имеют встроенную концепцию: например, NServiceBus определяет ConversationId в заголовках сообщений, а AMQP определяет поле id-корреляции в базовой модели сообщений.

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

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

0 голосов
/ 30 сентября 2018

Это нормально, но микросервисам не важно, как они получают сообщения.С их точки зрения входящие сообщения просто приходят.Затем у вас возникнет соблазн спроектировать вашу систему так, чтобы она зависела от некоторого глобального порядка событий, что сложно в распределенной масштабируемой системе.Не поддавайтесь этому искушению и спроектируйте вашу систему так, чтобы она передавалась только при локальном упорядочении событий (т. Е. При упорядочении в потоке событий, генерируемом агрегатором при получении событий + DDD).

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

...