【问题标题】:Event sourcing, Eventually Consistent, CQRS事件溯源,最终一致,CQRS
【发布时间】:2017-04-18 21:04:34
【问题描述】:

我目前遇到一个问题,希望您能在这里帮助我提出一些想法或最佳实践...

假设我有一个使用事件溯源和 CQRS 的应用程序。我有

  • 一个装有数字的绿色罐子
  • 一个装有数字的红锅
  • 我定义的设置,即应在 UI 中显示的罐数。
  • 包含要显示的数字的计算结果

我的应用程序的当前状态是

  • 红锅:10
  • 绿锅20个
  • 设置:红色
  • 结果:1​​0(红罐值)

我有一个订阅 Red Pot 服务、Green Pot 服务和设置服务的计算服务。我有一个 View Updater 服务,它另外订阅了 Calculation 服务并根据任何更改更新读取模型。

现在以下事件正在发生:

  1. 绿锅:25
  2. 环境:绿锅

View Updater 服务今天有点忙,更新视图模型有一些延迟。

计算服务处理 Green Pot 事件。它从读取模型(仍设置为红色)中获取设置并且什么都不做。

之后,计算服务处理设置事件。它从读取读取模型中获取绿色值(仍然是 20)并发送一个新事件(结果:20)

之后,View Updater 会处理这两个事件并更新读取模型。

在这种情况下,我的应用程序不一致 - 甚至最终都不一致。

有任何想法如何处理这样的事情吗?感谢您的任何想法:-)

【问题讨论】:

  • 您应该将事件的名称更改为更明确,例如GreenPotUpdatedRedPotUpdatedSettingsChanged

标签: cqrs event-sourcing consistency


【解决方案1】:

首先想到的是,不清楚您是否分享了对eventual consistency 的共同理解。 Martin Kleppmann 的talk 强调three ideas

  • 最终交付
  • 收敛
  • 无数据丢失

第二个想法是,您似乎在计算服务设计中引入了竞争条件。如果 RedPot、GreenPot 和 Setting 是单独的聚合/流,那么它们之间实际上没有任何时间绑定。来自这些来源的事件的到来本质上是活泼的。

乌迪·达汉写信Race Conditions Don't Exist

时间上的微秒差异不应影响核心业务行为。

这就是融合发挥作用的地方:您需要设计解决方案,以便即使消息的时间不同,它们也能达到相同的结果。这通常意味着您需要在模型中包含一些时钟或时间的概念,以及 defining the interval in which some result is true 的某种方式。

正如您定义的问题,计算服务生成的结果更多是关于缓存快照而不是维护历史记录。因此,考虑您遇到的问题的另一种方式是考虑计算服务不应接受来自读取模型的任何任意数据,而应接受与其正在使用的事件一致的数据。

Calculation service: "Hi, I can haz green pot as of event #40?"
Read model: "Sorry, no can haz, retry-after: 10 minutes"
Calculation service: "OK, I'll try again later."

【讨论】:

    【解决方案2】:

    Calculation 服务应该订阅并接收所有事件(GreenPotUpdatedRedPotUpdatedSettingsChanged)。

    Calculation 服务不能依赖最终一致的读取模型。相反,它应该保持自己的私有状态,确保以正确的顺序接收事件。

    【讨论】:

      猜你喜欢
      • 2018-01-16
      • 2019-01-31
      • 1970-01-01
      • 1970-01-01
      • 2016-07-11
      • 1970-01-01
      • 2018-11-15
      • 2019-09-22
      • 1970-01-01
      相关资源
      最近更新 更多