CQRS Event-Sourcing и собственная база данных для каждого микросервиса - PullRequest
0 голосов
/ 10 января 2019

У меня есть несколько вопросов, связанных с обработкой событий и cqrs в архитектуре микросервисов. Я понимаю, что после команды send какой-то микросервис выполняет ее и генерирует событие. Event-store подписывается на него и сохраняет в своей базе данных. Также некоторые ReadModel, основанные на этом событии, генерируют и сохраняют оптимизированные данные в базе данных чтения.

Мой первый вопрос: может ли микросервис иметь собственную базу данных и магазин? данные внутри тоже? Или, может быть, в рамках подхода к организации мероприятий на основе микросервисов не имеют своих собственных баз данных, и все хранится только внутри магазин событий?

Мой второй вопрос - когда я выполняю команду в микросервисе и Нужны ли некоторые данные для проверки? Мне нужно вызвать ReadModel или что? Предполагая, что микросервисы не имеют своих собственных баз данных, у меня нет выбор

1 Ответ

0 голосов
/ 10 января 2019

Может ли микросервис иметь свою собственную базу данных и хранить в ней данные?

Определенно, микросервис может иметь свою собственную базу данных. Но давайте использовать термины из ES / CQRS. База данных может представлять Хранилище событий (журнал только для добавления событий immutabale) и Чтение модели - некоторую базу данных, используемую для ответа на запросы, которая заполняется прослеживающимися событиями.

Таким образом, микросервис может иметь собственную модель чтения, заполненную событиями других микросервисов.

Или микросервис может обрабатывать команды и сохранять события в общем хранилище событий.

Или микросервис может обрабатывать команды и сохранять события в собственном хранилище событий.

Выбор за вами, и он зависит от степени разделения, которую вы хотите достичь между микросервисами.

Я бы поместил все события, которые обычно потребляются вместе, в одно хранилище событий. Это означает, что я должен иметь возможность запрашивать эти события и иметь в результате один упорядоченный поток.

когда я выполняю команду в микросервисе и мне нужны данные для проверки, нужно ли мне вызывать ReadModel или как?

Команда выполняется Агрегатом, который имеет свое собственное состояние. Это состояние создается путем обработки всех событий для этого агрегата, и это состояние следует использовать для проверки команды.

Вы не можете / не должны общаться с моделями чтения в обработчике команд , главным образом потому, что эти модели чтения не согласуются с агрегатным состоянием. Совокупное состояние соответствует.

Вы можете запросить чтение модели перед отправкой команды (чтобы убедиться, что она может быть отправлена). Но в обработчике команд вам нужно полагаться только на агрегатное состояние.

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

Но при обработке этой команды ({id:123, type:CREATE_USER, name:somename}) вы не можете проверить, выбрано ли "somename", потому что агрегатное состояние для пользователя 123 не содержит списка принятых имен. Вы можете запросить модель чтения AllUsernames, но она может быть устаревшей за миллисекунды, и какой-то другой пользователь уже может принять это «имя». Таким образом, в этом сценарии вы найдете дублирование при добавлении имен для чтения модели. И в этот момент вы можете выполнить некоторые действия по компенсации - обычно введите команду, чтобы приостановить пользователя с дублированным именем и попросить его перерегистрировать или как-то изменить его имя.

Это может показаться странным, но если у вас действительно распределенная система с несколькими репликами списка пользователей, у вас возникнет та же проблема, так почему бы просто не принять тот факт, что данные всегда не полностью согласованы, а просто разобраться с это?

...