Domain driven design DDD、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设计模式,这意味着 每个微服务都有自己的聚合映射,映射现实世界问题的域 聚合的状态将从事件存储重建 每个事件将表示聚合中的状态更改,并将通过消息代理传输给对更改感兴趣的任何服务 每个微服务在其自己的域内都是事务性的 每个微服务最终将与其他域保持一致 每个微服务将根据其他微服务发出的事件构建自己的视图模型 所以这个例子让我们假设我们有一个银行

因此,我将通过使用一个例子来解释这个问题,因为它使一切变得更加具体,希望能够减少歧义

架构非常简单

1微服务1聚合事务边界

每个微服务将使用CQRS/ES设计模式,这意味着

  • 每个微服务都有自己的聚合映射,映射现实世界问题的域
  • 聚合的状态将从事件存储重建
  • 每个事件将表示聚合中的状态更改,并将通过消息代理传输给对更改感兴趣的任何服务
  • 每个微服务在其自己的域内都是事务性的
  • 每个微服务最终将与其他域保持一致
  • 每个微服务将根据其他微服务发出的事件构建自己的视图模型
所以这个例子让我们假设我们有一个银行系统

  • 活期账户
    microservice负责映射客户活期账户。。。取款、存款
  • 奖励
    微服务将负责对银行提供的任何奖励进行盘点
  • 航空里程
    微服务将负责监控来自
    往来账户
    的所有交易,并通过我们的奖励微服务向客户提供奖励
因此,问题在于
航空里程
微服务是否应该根据自己的视图模型做出决策,该视图模型是根据
往来账户
中的事件更新的,同样,在选择应该向客户发放的奖励时也应该这样做

在局部视图模型上进行决策的缺点

  • 复制有关如何维护这些视图的域逻辑
  • 视图中的bug可能会传播错误的奖励
  • 损坏的视图模型上的状态更改(即发出的事件)可能会在其他服务中产生后果,这些服务会自行决定这些事件
对局部视图模型作出决策的优势

  • 系统不需要不断地查询拥有该域的微服务

  • 系统应该更快,资源密集度更低

    或者它应该使用来自服务的事件来触发对拥有域的聚合的查询,在这样做时,我们接受这样一个事实,即视图模型可能会损坏,但最终决策应该始终与拥有域的聚合协商

请注意,上述问题并不是我对体系结构的理解,本文的目的是了解如何在微服务环境中有效地使用该体系结构,以保持每个服务的解耦,同时避免级联损坏场景,而不会引起服务之间的大量交谈

因此,问题在于,航空里程微型服务是否应该根据其自身的视图模型做出决策,该视图模型将根据来自经常账户的事件进行更新,同样,还应该选择应该向客户发放的奖励

每个使用者使用生产者计算的表示的本地副本

因此,如果
air miles
需要来自
current-account
的信息,它应该查看由
current-account
服务计算的视图的本地副本

关键思想是:微服务应该相互隔离;您应该能够重新设计和部署一个,而不会影响其他

所以试试这个思维实验——假设我们有这三个微服务,但都保存当前状态的快照,而不是事件。一切正常,然后想象一下,
经常账户
维护人员发现事件源实现可以更好地服务于业务

更改
经常账户
是否需要对
航空里程
服务进行相应更改?如果是这样,我们真的可以说这些服务是相互隔离的吗

对局部视图模型作出决策的优势

我并不特别喜欢这些“优势”;首先,它们由性能轴主导(请记住,性能优化的第二条规则是“尚未”)。第二,他们假设服务边界绘制正确;也许绩效问题是责任分离需要审查的证据

因此,问题在于,air miles微服务是否应该根据其自身的视图模型做出决策,该视图模型根据来自经常账户的事件进行更新,同样,还应该选择应向客户发放的奖励

对。事实上,您应该修改您的体系结构,甚至创建更多的微服务。我的意思是,作为一个事件驱动架构(也是一个事件源架构),您的微服务有两个职责:它们需要保留两个不同的模型:写模型和读模型

因此,对于每个聚合,都应该是一个只保留写模型的微服务,也就是说,它只处理命令,而不构建读模型

然后,对于每个读取/查询用例,您应该有一个构建完美读取模型的微服务。如果您需要保持聚合微服务干净(您应该这样做),这是必需的,因为一般来说,读取模型需要来自多个聚合类型/有界上下文的数据。读取模型可能会跨越有界上下文边界,聚合可能不会。所以你看,如果你需要完全尊重DDD,你真的没有选择的余地

有人说域事件应该是隐藏的,只对所拥有的微服务是本地的。我不同意。在事件驱动的体系结构中,dom