events - 每个微服务的 CQRS 事件源和自己的数据库

标签 events microservices cqrs event-sourcing

我对微服务架构中的事件溯源和 cqrs 有一些疑问。 我知道在发送命令后,一些微服务会执行它并发出事件。事件存储订阅它并保存在他的数据库中。还有一些基于此事件的 ReadModel 在读取数据库中生成和保存优化数据。

My first question is - Can microservice has his own database and store data inside it too? Or maybe in event-sourcing approach microservices don't have their own databases and everything is only stored inside event store?

My second question is - when I execute command in microservice and need some data for validation purposes do I need call ReadModel or what? Assuming microservices haven't got their own databases I have no choice?

最佳答案

Can microservice has his own database and store data inside it too?

当然,微服务可以有自己的数据库。但是让我们使用来自 ES/CQRS 的术语。数据库可以表示事件存储(不可变事件的仅附加日志)和读取模型 - 一些用于回答由处理事件填充的查询的数据库。

因此,微服务可以拥有自己的读取模型,该模型由来自其他微服务的事件填充。

或者微服务可以处理命令并将事件保存到共享事件存储。

或者微服务可以处理命令并将事件保存到自己的事件存储中。

选择权在您,这取决于您希望在微服务之间实现的分离程度。

我会将所有通常一起消费的事件放入同一个事件存储中。这意味着我应该能够查询这些事件并得到一个有序的流。

when I execute command in microservice and need some data for validation purposes do I need call ReadModel or what?

命令由聚合体执行,聚合体有自己的状态。此状态是通过处理此聚合的所有事件构建的,此状态应用于验证命令。

cannot/should not talk to Read Models in the command handler ,主要是因为那些读取模型与聚合状态不一致。聚合状态是一致的。

您可以在发送命令之前查询读取模型(以确保它可以发送)。但是在命令处理程序中,您只需要依赖聚合状态。

有一个著名的注册用户要求唯一名称的案例。作为主要验证,在您的 UI 代码中,您可以查询读取模型并告诉用户输入的名称已被使用。如果未使用名称,则 UI 让用户发出命令。我假设您的聚合根是用户。

但是在处理这个命令时 ({id:123, type:CREATE_USER, name:somename}) 你不能检查“somename”是否被占用,因为用户 123 的聚合状态不包含取名列表。您可能会查询一些 AllUsernames 读取模型,但它可能是毫秒级的,并且其他一些用户可能已经使用了这个“somename”。因此,在这种情况下,您会发现在将名称添加到读取模型时出现重复。那时你可以做一些补偿行动 - 通常发出命令暂停具有重名的用户并要求他重新注册或以某种方式更改他的名字。

这可能看起来很奇怪,但如果你有一个真正的分布式系统,有多个用户列表副本,你也会遇到同样的问题,那么为什么不接受数据总是不完全一致的事实,并处理是吗?

关于events - 每个微服务的 CQRS 事件源和自己的数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54125607/

相关文章:

nhibernate - 使用 NHibernate 进行事件溯源

java - 使用系统证书签署 apk

Javascript 对象 - 强制触发事件

spring - 如何将不同的 “microservices” 整合到一个事务中?

docker - 在我的 CI 管道中使用 docker-compose 与 codeship-services

azure - 我是否使用 Azure 表存储或 SQL Azure 作为我们的 CQRS 读取系统?

javascript - 获取函数的回调以将值返回给父函数

javascript - 防止子元素触发 jQuery 事件

architecture - SOA 与 NuGet 包

asp.net-core - 如果有 CQRS、DTO 和实体,如何验证输入数据?