2017-02-10 75 views
2

命令查询责任分离/事件采购体系结构非常适合我开始的一个项目,该项目每年将涉及与人们的健康保险保险有关的每年约10亿笔金融交易。主要优势包括审计历史记录,可扩展性,跨多个团队实施异步兼容的UI,从读取数据库中分离这些事务,通过事件队列缓解向间歇性连接的现场办公室传输状态,并应对显着的业务逻辑变化整个系统的生命周期。CQRS体系结构优化和变化

然而,有些地方CQRS/ES将会出现问题,例如为1亿人分配数字ID,最终一致性不可接受的用户安全性。该系统还有一些CRUD性质的区域,不受CQRS/ES的好处。最后,我们将在不同的团队和公司中拥有大量开发人员,并且最好能有不需要CQRS/ES能力的领域。是否有可能采用混合方法,其中一些区域不是事件源?我们是否可以同时读取和写入两边的相关表?

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

我期待着每年有大约十亿次的活动,需要跟踪大约四年的历史。我们可以快照并存档较早的事件吗?

是否有事件采购?例如,一个在线商店系统AddLineItem事件可能包含每个单元的订单项价格,但依赖于读取面来在发票上拉取和渲染产品名称。另一个在线商店可能会在事件数据中包含该名称。你如何选择在活动中包含什么?在健康保险方面,它可能会限制“如果”分析可以运行 - 如果我们没有包括被保险人的年龄,我们就不可能模拟需要的政策吗?

有没有一种有趣的方式来模拟事件的事件?例如,管理员进入系统后,产品的价格将在某个日期发生变化。我想快照将是一个价格时间表。我们可以添加一个后期的ProductPriceChanged事件吗?运行“假设”情景时,我们是否可以伪造这些事件? (为了避免版本号和并发检测问题,这样的聚合将不得不很少改变。)通常声称CQRS/ES使系统更容易适应未来的业务流程变化。我理解这样的观点:命令以无所不在的语言列出事件使得讨论和重新配置它们变得更容易,事件采购消除了RDBMS模型的一些僵化。但会不会发生任何变化,将会打破事件的重播?随着系统的变化,你会不会得到许多版本化的事件?例如,在网上商店通过更改标准来评估客户是否为金卡持有人?你可以拍摄一切吗?你将如何对这些变化进行后期处理?同样,你必须小心依赖注入,注入的所有依赖都不会影响业务逻辑,否则你会破坏重放?

任何想法为什么它与.NET世界相关联,在行业的其他领域较少受欢迎程度?

巨大即使只是阅读也要感谢。

回答

4

是否有可能采用混合方法,其中一些区域不是事件源?

当然。

我们可以只对同步读取和写入双方相关的表?

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

待办事项CQRS架构的总实体简化快照的缓存失效?

不多?可以用来使缓存无效的记录簿中发生了一个表示已发生写入事件的概念,这并不是特别的CQRS想法。这并不简单 - 只是额外的工作无论如何都在范围之内。

我们可以快照并存档较早的活动吗?

是的,但是......通常情况下,将长寿命实体的历史分解为更短的剧集,并将状态从一个剧集转移到下一个剧集更容易 - 例如,考虑滚动财务期结束时的分类帐。然后,您将任何已结束的聚合历史记录归档。

你如何选择在活动中包含什么?

查看此聚合所需的状态以建立/维护/恢复业务不变量。其他一切都可以进去洗。这通常意味着报告(读取模型)是由多个聚集组成的,并且可能还有文档。

有没有一种有趣的方法来模拟事件的事件?

关于事件的事件很混乱。关于流程的活动非常棒。

我们可以改为添加一个后期的ProductPriceChanged事件吗?

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

,但不会在事件内的任何更改将中断事件的重演?

不,但是您需要维护有关事件表示的规则以确保事实如此。 Greg Young正在写作Versioning in an Event Sourced System作为电子书。

模式中的快速和脏字段是可选的;你可以添加它们,或删除它们,但是你永远不会改变它们的含义。消费者为他们想要阅读的任何内容提供默认值,并且“必须忽略”他们不了解的条目。

随着系统的变化,你会不会得到许多版本化的事件?例如,在网上商店通过更改标准来评估客户是否为金卡持有人?

不清楚这是什么问题。可能有几个事件表示(取决于预期的模式和考虑哪些默认值),但它仍然只是一个事件。系统做出的决定由事件记录,所以随着时间的推移并不真正进入。

同样你必须要小心的依赖注入是不被注入会影响业务逻辑之间的依赖关系,否则你打破重播?

业务逻辑都住在领域模型中,领域模型居住在洋葱的中心;脱离现实世界。所以你不应该注入任何在现实世界中引入副作用的依赖。这些通常是异步处理的(我们成功保存了这些事件,因此可以计划副作用)。

任何想法为什么它与.NET世界相关联,在行业的其他领域较少受欢迎程度?

人。 Udi Dahan和Greg Young都有.NET背景。在PHP中也很流行,因为Mathias Verraes有这样的背景。

你会怎么建议我坚持非ES聚合实体?

文档存储? RDBMS?平面文件? Polyglot持久性很好。

我可能会错过这回答这个问题 - 如果业务不变是订单行项目,这是否包括产品名称或价格?

产品标识和数量可能已足够。如果您所在的公司的报价可能与目录中列出的报价有所不同,那么可能是报价。

我的意思是如果一个聚合的业务逻辑改变,但过去的事件仍然需要处理旧的方式。

一个关键的想法是事件的含义不应该改变;他们描述了状态的变化。所以如果你发现“新版本的事件”意味着不同的事情,那么你确实有一个新的事件。见杨的书。

聚合业务逻辑 - 决定如何从一个状态发展到下一个;这确实会改变。但它不会改变给定总量实际所处的状态。

例如,您可能会发现某些状态不应该可达。这就是业务逻辑 - 汇总不应该写入新事件来结束该状态。这不会以任何方式影响当前处于不可达状态的聚合;他们仍然存在,因为那是历史给他们的地方。通过给他们更多的事件让他们摆脱这种状态。

+0

'这听起来像个坏主意' - 你会如何建议我坚持非ES聚合实体? “无论如何,”说得好! “将任何生命即将结束的聚合体的历史归档 - 就不够了,因为对于我们来说,在某人死后有4年的生命结束。 “国家需要...保持业务不变” - 我可能会想念这个问题如何回答这个问题 - 如果业务不变是订单项,那么这包括产品名称还是价格? – Chris

+0

错误拼写 - 我故意将事件从PriceChangeScheduled更改为**后期** PriceChanged,仅在达到该日期后才会用于重播。 “由系统做出的决定是由事件记录的 - ”你在我的理解中填补了一个空白,我的意思是如果一个聚合的业务逻辑改变了,但过去的事件仍然需要以旧的方式处理。我会重新阅读你的答案(再次)并阅读杨的书。非常感谢,非常感谢。 – Chris