Domain driven design DDD、CQRS/ES&;微服务应根据微服务';我们的观点还是总体?
因此,我将通过使用一个例子来解释这个问题,因为它使一切变得更加具体,希望能够减少歧义 架构非常简单 1微服务1聚合事务边界 每个微服务将使用CQRS/ES设计模式,这意味着Domain driven design DDD、CQRS/ES&;微服务应根据微服务';我们的观点还是总体?,domain-driven-design,microservices,cqrs,event-sourcing,Domain Driven Design,Microservices,Cqrs,Event Sourcing,因此,我将通过使用一个例子来解释这个问题,因为它使一切变得更加具体,希望能够减少歧义 架构非常简单 1微服务1聚合事务边界 每个微服务将使用CQRS/ES设计模式,这意味着 每个微服务都有自己的聚合映射,映射现实世界问题的域 聚合的状态将从事件存储重建 每个事件将表示聚合中的状态更改,并将通过消息代理传输给对更改感兴趣的任何服务 每个微服务在其自己的域内都是事务性的 每个微服务最终将与其他域保持一致 每个微服务将根据其他微服务发出的事件构建自己的视图模型 所以这个例子让我们假设我们有一个银行
- 每个微服务都有自己的聚合映射,映射现实世界问题的域
- 聚合的状态将从事件存储重建
- 每个事件将表示聚合中的状态更改,并将通过消息代理传输给对更改感兴趣的任何服务
- 每个微服务在其自己的域内都是事务性的
- 每个微服务最终将与其他域保持一致
- 每个微服务将根据其他微服务发出的事件构建自己的视图模型
microservice负责映射客户活期账户。。。取款、存款活期账户
微服务将负责对银行提供的任何奖励进行盘点奖励
微服务将负责监控来自航空里程
的所有交易,并通过我们的奖励微服务向客户提供奖励往来账户
航空里程
微服务是否应该根据自己的视图模型做出决策,该视图模型是根据往来账户
中的事件更新的,同样,在选择应该向客户发放的奖励时也应该这样做
在局部视图模型上进行决策的缺点
- 复制有关如何维护这些视图的域逻辑
- 视图中的bug可能会传播错误的奖励
- 损坏的视图模型上的状态更改(即发出的事件)可能会在其他服务中产生后果,这些服务会自行决定这些事件
- 系统不需要不断地查询拥有该域的微服务
- 系统应该更快,资源密集度更低 或者它应该使用来自服务的事件来触发对拥有域的聚合的查询,在这样做时,我们接受这样一个事实,即视图模型可能会损坏,但最终决策应该始终与拥有域的聚合协商
air miles
需要来自current-account
的信息,它应该查看由current-account
服务计算的视图的本地副本
关键思想是:微服务应该相互隔离;您应该能够重新设计和部署一个,而不会影响其他
所以试试这个思维实验——假设我们有这三个微服务,但都保存当前状态的快照,而不是事件。一切正常,然后想象一下,经常账户
维护人员发现事件源实现可以更好地服务于业务
更改经常账户
是否需要对航空里程
服务进行相应更改?如果是这样,我们真的可以说这些服务是相互隔离的吗
对局部视图模型作出决策的优势
我并不特别喜欢这些“优势”;首先,它们由性能轴主导(请记住,性能优化的第二条规则是“尚未”)。第二,他们假设服务边界绘制正确;也许绩效问题是责任分离需要审查的证据
因此,问题在于,air miles微服务是否应该根据其自身的视图模型做出决策,该视图模型根据来自经常账户的事件进行更新,同样,还应该选择应向客户发放的奖励
对。事实上,您应该修改您的体系结构,甚至创建更多的微服务。我的意思是,作为一个事件驱动架构(也是一个事件源架构),您的微服务有两个职责:它们需要保留两个不同的模型:写模型和读模型
因此,对于每个聚合,都应该是一个只保留写模型的微服务,也就是说,它只处理命令,而不构建读模型
然后,对于每个读取/查询用例,您应该有一个构建完美读取模型的微服务。如果您需要保持聚合微服务干净(您应该这样做),这是必需的,因为一般来说,读取模型需要来自多个聚合类型/有界上下文的数据。读取模型可能会跨越有界上下文边界,聚合可能不会。所以你看,如果你需要完全尊重DDD,你真的没有选择的余地
有人说域事件应该是隐藏的,只对所拥有的微服务是本地的。我不同意。在事件驱动的体系结构中,dom