События CQRS между несколькими сервисами

У нас есть микросервис, который отслеживает события, давайте пока назовем его AuditService. Он прослушивает события аудита (AuditEvent) на rabbitmq. Любой, кто хочет вызвать AuditService, должен создать и запустить AuditEvent. Мы разделили AuditEvent pojo в общем модуле, чтобы им можно было делиться.

В AuditService есть прослушиватель событий, который прослушивает AuditEvent из очереди rabbitmq. Когда мы получаем сообщение, мы затем обрабатываем / проверяем AuditEvent, а затем сохраняем его в таблице базы данных AuditEntry.

Затем мы хотим опубликовать другое событие. Назовем это AuditPublishEvent. Итак, чтобы сделать это, мы создаем другую команду (AuditPublishCommand), которая, в свою очередь, запускает AuditPublishEvent. Это событие снова для очереди, и любая служба, публикующая AuditEvent, будет его прослушивать. Будет один сервис для отправки по электронной почте, другой для отправки в виде push и т. Д.

На данный момент то, что мы делаем в AuditService,

Listen for AuditEvent
  |
  v
Trigger AuditEvent event handler
  |
  v
Validate audit event and process it
  |
  v
Save it to the database
  |
  v
If save is successful then send AuditPublishEvent to queue via AuditPublishCommand

Обратите внимание, что последняя часть должна быть синхронной, что означает, что если сохранение базы данных завершилось неудачно, мы не хотим отправлять электронное письмо или что-то подобное. В настоящее время это делается путем вызова commandGateway из обработчика событий в AuditService, правильно ли вызывать commandGateway из EventListener, если нет, какая альтернатива?

Вопрос в том, является ли это правильным способом / передовой практикой использования фреймворка Axon и Spring?


person tjack18    schedule 27.06.2018    source источник
comment
у вас есть услуги чтения и записи? если у вас есть отдельная служба чтения, вы можете отправить SendEmailCommand в службу электронной почты внутри обработчика событий службы чтения после сохранения данных.   -  person Keaz    schedule 27.06.2018


Ответы (1)


Трудно сказать, является ли это лучшим способом решения проблемы, поскольку для этого потребуется гораздо больше информации о вашем домене. Что я могу сказать, так это то, что вы делаете технически в порядке. Вы упомянули, что не уверены, публикуется ли событие, опубликованное после сохранения AuditEvent, только после фиксации изменений в базе данных. Это зависит от того, как публикуется мероприятие. Если вы используете EventBus для его публикации и SpringAMQPPublisher, вы в безопасности. Если вы опубликуете его напрямую, это может быть не так.

Axon использует unitOfWork для координации действий на разных этапах обработки. Обработчики вызываются на «начальном» этапе. Фиксация базы данных выполняется на этапе после «фиксации». Если вы хотите, чтобы сообщение было отправлено AMQP после фиксации, зарегистрируйте обработчик для фазы afterCommit. Обработчики для этой фазы не вызываются при откате. Вы можете добавить UnitOfWork в качестве параметра к аннотированному методу @EventHandler. Axon автоматически введет его за вас.

person Allard    schedule 28.06.2018