1)领域事件和事务一致性和2)集成事件和最终一致性之间的关系是啥
Posted
技术标签:
【中文标题】1)领域事件和事务一致性和2)集成事件和最终一致性之间的关系是啥【英文标题】:What is the relationship between 1) Domain Events and Transactional consistency and 2) Integration Events and Eventual consistency1)领域事件和事务一致性和2)集成事件和最终一致性之间的关系是什么 【发布时间】:2019-03-05 06:05:10 【问题描述】:我了解事务一致性和最终一致性之间的区别。假设我正在开发一个应用程序,其中有三个微服务,并且有一个消息总线,当引发集成事件时,它会在它们之间发送消息,这意味着最终的一致性。例如,微服务 B 发布了一个集成事件,微服务 A 在两小时后处理它,因为微服务 B 在事件发布时已关闭并且消息是持久的 - 这很好。
我的理解方式;微服务内部应该有事务一致性 - 聚合 A 可能会发布聚合 B 感兴趣的域事件,因此会引发域事件并且对数据库的任何更新都在同一事务中执行。
我不明白 CQRS 如何适应这种事务一致性/最终一致性场景,因为:
-
我无法使用事务一致性,因为读取模型 (NoSQL) 和写入模型 (SQL 服务器) 无法在同一事务中更新。
我无法使用消息总线,因为更新读取模型不是集成事件,即读取模型和写入模型包含在同一个微服务中。
对于 CQRS,我相信有两种选择:
-
如果将事件存储用于写入端,那么读取端可以轮询它 - 这解决了问题,因为没有事件。
如果将事件日志/关系数据库用于写入端,则会引发域事件以更新读取端。
如果选择了选项二,那么我如何保证读取模型最终会与写入模型同步?例如,当事件引发时,读取模型可能会关闭。
【问题讨论】:
【参考方案1】:在将 DBMS 系统用于只读系统时,CQRS 可以降低针对乐观锁的脆弱性,从而符合最终一致性的概念。分离您的命令和查询使您能够进行有效的读/写,而不管两者的可用性如何。
1)。如果由于乐观锁定而希望拥有高可用性端点,则不建议使用事务一致性。
2)。您绝对可以使用消息总线来更新您读取的模型,因为排队的概念并不是上下文间数据同步的同义词。
【讨论】:
感谢 +1 对“上下文间数据同步”的引用。在标记答案之前,我还有两个问题。 Q1) 读取模型数据访问是否包含在与写入模型数据访问相同的微服务中? Q2) 是否会使用集成事件或领域事件来更新读取数据库 (MongoDB)? Q1) 微服务是一个 API 和一个单一的有界上下文。是否建议将读取模型和写入模型包含在其中? Q2) 你是说它应该是一个集成事件吗?我认为当一个微服务发布事件而另一个微服务处理它时,集成事件是合适的。让相同的微服务发布和处理集成事件“可以”吗? 谢谢。我相信您刚刚回答了我对问题 1 的最后评论。您能回答我对问题 2 的最后评论吗?再次感谢。 谢谢。您是说在微服务内部有一个队列,在外部有另一个队列。外面的那个是用来做微服务之间的通信的?如果答案是肯定的,那么您是否知道这样做的任何示例,例如在 GitHub 上?再次感谢。【参考方案2】:从技术上讲,聚合是 DDD 中的原子性单位,因此不需要保证通过域事件进行通信的聚合之间的一致性。来自埃文的书:
AGGREGATE 是一组关联对象,我们将其视为 用于数据更改目的的单位...不变量,它们是 每当数据更改时必须维护的一致性规则,将 涉及聚合成员之间的关系。任何规则 spans AGGREGATES 不会一直是最新的 ...但是在 AGGREGATE 中应用的不变量将被强制执行 随着每笔交易的完成。
然而,出于实际目的,我开发的大多数服务确实将域事件的处理包装在为处理初始请求而创建的相同环境事务中。分布式应用程序很难设计和调试,而不必担心服务内部补偿操作之类的事情!
我目前正在使用MediatR 库将域事件处理程序与生成它们的原始命令/请求处理程序分离。它具有与消息传递系统非常相似的发送/处理语义,并包括一个用于验证和预处理/后处理的强大的类似中间件的管道。
【讨论】:
【参考方案3】:如果选择了选项二,那么如何保证读取模型最终与写入模型同步?
解决方案是两种选择的混合:
在执行命令时引发域事件。
将域事件存储在写入模型的事件存储中。此任务由静态轻量级订阅者执行。事件存储在执行命令的同一事务中。
工作进程或批处理进程获取事件存储的事件并通过消息队列发送。
订阅者从队列中取出它们并更新读取模型。
这样您就不会丢失事件。如果读取模型由于某种原因不可用,worker 将再次重新处理该事件。
【讨论】:
以上是关于1)领域事件和事务一致性和2)集成事件和最终一致性之间的关系是啥的主要内容,如果未能解决你的问题,请参考以下文章
Shashlik.EventBus.NET 事件总线,分布式事务最终一致性简介