#mongodb #go #rabbitmq #cqrs #event-sourcing
#mongodb #Вперед #rabbitmq #cqrs #источник событий
Вопрос:
Ситуация
Чтобы лучше понять концепции CQRS, поиска событий и асинхронного взаимодействия служб, я создавал небольшую систему с использованием Go, MongoDB и RabbitMQ. Это включает в себя следующее:
- Command API: предоставляет API для приема и обработки команд, а затем записи событий в коллекцию MongoDB (называемую «события»)
- Издатель событий: просматривает коллекцию «события» на предмет изменений и публикует их в RabbitMQ
- Потребитель событий: получает события от RabbitMQ и использует их для обновления коллекции MongoDB, оптимизированной для чтения
- API запросов: предоставляет API для возврата данных из материализованной коллекции
(Я предполагаю, что аналогичный набор приложений повторяется для каждого микросервиса в системе, и все они взаимодействуют асинхронно через RabbitMQ)
Проблема
Я чувствую, что хорошо понимаю эти концепции на высоком уровне, однако при создании этой системы у меня возникли некоторые проблемы с деталями. Я обнаружил, что мне нужно либо:
-
Используйте BSON в качестве полезной нагрузки RabbitMQ, чтобы сделать вещи «простыми» для издателя событий — такое ощущение, что MongoDB просачивается в остальную часть дизайна, поскольку в противном случае я бы не выбрал BSON
-
Сделайте издателя событий осведомленным обо всех типах событий, чтобы он мог правильно преобразовать сохраненное событие из BSON в JSON (например, переписать даты и UUID в виде строк) для публикации в шине сообщений — это, похоже, пахнет, поскольку различные типы событий должны быть определены не менее чем в трех отдельных местах (сторона команды, сторона запроса и издатель событий).
Вопросы
-
Является ли этот тип проблемы обычным явлением для проекта, использующего CQRS Event Sourcing Message Bus, или мой подход в корне ошибочен?
-
Если это соответствует курсу, какой из двух вышеупомянутых вариантов лучше использовать в производственных условиях?
Мои поиски ничего не дали об этой проблеме, но если вы знаете статью или сообщение в блоге, в которых она рассматривается, этого, вероятно, будет достаточно.
Ответ №1:
Существует концепция обновления событий. Целью средств обновления событий является преобразование событий, поступающих из хранилища событий в виде нетипизированной структуры данных, в типизированную структуру данных перед их публикацией (также перед гидратацией агрегатов). Они часто используются при управлении версиями. Помните, что чем больше система растет, тем больше шансов, что ваши типы событий изменятся, поэтому вы не сможете просто десериализовать из json / bson.
Как только ваши события будут введены правильно, сериализуйте их в json, чтобы передать их в шину и десериализовать их обратно на другой стороне.
типы событий должны быть определены не менее чем в трех отдельных местах (сторона команды, сторона запроса и издатель событий)
Просто определите свои типы событий в общей библиотеке.
Кроме того, это не связано, но вам действительно не нужна шина. Они вызывают больше проблем, когда дело доходит до перестройки прогнозов, поскольку они не отслеживают последнее событие чтения. Грег Янг рассказывал об этом где-то на YouTube (найти его не составит труда).
Комментарии:
1. Интересно, я не слышал об этой концепции обновления событий. Для этого приложения я понимаю, что шина сообщений является серьезным излишеством, но я хотел получить представление о том, как это может быть построено как часть гораздо более сложной системы. Я посмотрю на выступление Грега Янга, на случай, если в нем есть что-то большее, чем я понимаю. Спасибо!
2. Что касается разделяемой библиотеки, у меня создалось впечатление, что это было бы нежелательно, но я думаю, что я путал эту ситуацию, когда различные части принадлежат одной команде, с ситуацией, когда библиотека может быть разделена между командами, создавая зависимости между командами.
3. Я понимаю вашу борьбу, но в какой-то момент вам нужно заключить контракт между службами, и события являются идеальным выбором для этого. Вы также можете использовать средства обновления событий с обеих сторон, чтобы минимизировать влияние изменений, нарушающих контракт события.