命令查询责任分离/事件来源体系结构非常适合我正在启动的项目,该项目每年将发生约10亿笔与人们健康保险相关的财务交易。关键好处是审核历史记录,可伸缩性,在多个团队中实施异步兼容的UI,将这些事务从读取的数据库中分离出来,简化了通过事件队列将状态传输到间歇连接的现场办公室的过程以及应对重大的业务逻辑更改在整个系统生命周期中。

但是,在某些地区,CQRS / ES可能会出现问题,例如,为1亿人分配数字ID,最终安全性不可接受的用户安全性。系统中还有一些区域本质上是CRUD的,不能从CQRS / ES中受益。最后,我们将在不同的团队和公司中拥有大量的开发人员,并且拥有不需要CQRS / ES能力的领域将是一件好事。在某些区域不是事件来源的地方,是否可以采用混合方法?我们可以仅在读写侧同步相关表吗?

CQRS架构的聚合实体是否简化了快照缓存失效?任何更新可能缓存的聚合实体的事件都可以由失效器监听,并且给定的聚合实体比关系实体的粒度更粗,我们可以区分写事件,这个问题是否可以解决?

我预计每年大约有十亿个事件,并且需要追踪约4年的历史。我们可以快照和存档较旧的事件吗?

有多少 Activity 来源?例如,一个在线商店系统AddLineItem事件可能包括每单位订单项的价格,但依赖于读取方来提取发票上的产品名称并将其呈现。另一个在线商店可能在事件数据中包含该名称。您如何选择要包含在 Activity 中的内容?在健康保险中,这可能会限制可以执行“假设条件”分析的内容-如果我们未包括被保险人的年龄,我们将无法切实地模拟需要该保险的年龄?

有没有一种有趣的方式来建模有关事件的事件?例如,管理员进入系统,产品的价格将在将来的某个日期改变。我想快照将是一个价格时间表。我们是否可以添加一个后期ProductPriceChanged事件?在运行“假设”场景时,我们可以伪造此类事件吗? (为了避免版本号和并发检测问题,必须很少更改此类聚合。)

通常声称CQRS / ES使系统更容易适应 future 的业务流程变更。我理解这样的论点,即命令以无所不在的语言列出事件使讨论和重新配置事件变得更加容易,事件源消除了RDBMS模型的某些刚性。但是,事件中的任何更改不会破坏事件的重播吗?随着系统的变更,您最终不会遇到许多版本化的事件吗?例如,在一家在线商店中,通过更改标准来评估客户是否是金卡持有人?您可以快照所有内容吗?您如何将这些更改的日期更新?同样,您是否必须小心依赖项注入(inject),即注入(inject)的任何依赖项都不会影响业务逻辑,否则会破坏重播?

知道为什么它与.NET世界相关联,而在其他行业中却不那么流行吗?

巨大的甚至感谢您的阅读。

最佳答案



当然。



在许多情况下,这听起来像是个坏主意。



不多? CQRS并不是一个特别的概念,即有事件表明已对记录簿进行写操作,该事件可用于使缓存无效。这没有任何简单的方法,只是多余的工作仍然在范围内。



是的,但是...从一个长期存在的实体被分解成较短的情节并将状态从一个情节过渡到下一个情节的历史通常更容易思考-例如,考虑在末尾滚动账本一个财政期间。然后,您可以归档寿命终止的任何聚合的历史记录。



查看此聚合所需的状态,以建立/维护/恢复业务不变式。其他一切都可以洗。这通常意味着报告(读取模型)是从多个汇总中汇总的,也可能是文档。



关于事件的事件是混乱的。关于流程的事件真棒。



拼写错误-尝试PriceChangeScheduled。注意:建模时间很重要;除非外界提及,否则领域模型不应注意到时间的流逝。



不,但是您需要维护有关事件表示的规则,以确保是这样。格雷格·杨(Greg Young)正在将Versioning in an Event Sourced System作为电子书编写。

模式中的quick和dirty-字段是可选的;您可以添加或删除它们,但绝不能更改它们的含义。消费者为他们想要阅读的任何内容提供默认值,并“忽略”他们不理解的条目。



我不清楚这是哪个问题。一个事件可能有几种表示形式(取决于期望的模式和所考虑的默认值),但它仍然仅仅是一个事件。系统做出的决定由事件记录,因此随着时间的流逝,版本化并没有真正纳入其中。



业务逻辑全都生活在领域模型中,而领域模型则生活在洋葱的中心。与现实世界脱节。因此,您不应该注入(inject)任何在现实世界中引入副作用的依赖项。这些通常是异步处理的(我们成功保存了这些事件,因此可以安排副作用)。



人。 Udi Dahan和Greg Young都有.NET背景。在PHP中也很受欢迎,因为Mathias Verraes具有这种背景。



文件存储? RDBMS?平面文件?多语言持久性很好。



产品ID和数量可能就足够了。如果您所在的公司的报价可能与目录中列出的价格不同,则可能是报价。



一个关键思想是事件的含义不应该改变。他们描述了状态的变化。因此,如果您发现“事件的新版本”的含义有所不同,那么您确实有一个新事件。参见杨的书。

聚合业务逻辑-决定如何从一种状态发展到另一种状态;确实会改变。但这不会改变给定聚合的实际状态。

例如,您可能发现某些状态不可达。这是业务逻辑-聚合不应编写新事件以使其最终处于该状态。这不会以任何方式影响当前处于无法访问状态的聚合;他们仍然在那里,因为那是历史把他们放在那儿的地方。通过为他们提供更多事件,可以将其从该状态中移出。

关于architecture - CQRS体系结构的优化和变化,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42167912/

10-11 09:02