【问题标题】:Event sourcing concurrency issue across multiple instances跨多个实例的事件溯源并发问题
【发布时间】:2018-12-05 12:24:57
【问题描述】:

我是事件溯源概念的新手,所以有些时候我不明白。其中之一是如何处理以下情况:

我有 2 个服务实例。他们都听一个事件队列。有两条消息:CreateUser 和 UpdateUser。第一个实例选择 CreateUser,第二个实例选择 UpdateUser。出于某种原因,第二个实例会更快地处理它的命令,但不会有要更新的用户,因为它不是创建的。

我在这里做错了什么?

【问题讨论】:

  • 首先,我要澄清你的问题。我假设您在这里谈论命令。 Еvents 不是命令,命令不是事件。 CreateUser 听起来像一个命令。 UserCreated - 一个事件。
  • 我说的是缺乏适当的上下文(你的问题并没有把大部分内容放在桌子上),但我想到的第一件事是:UpdateUser 消息在 CreateUser 完成之前永远不应该存在它的工作......
  • @AlexanderCapone 事件溯源与实例获取消息无关。您可能对消息队列/总线感到困惑。您还应该更清楚地说明为什么需要同一服务的 2 个实例。

标签: domain-driven-design event-sourcing


【解决方案1】:

我在这里做错了什么?

审核:Race Conditions Don't Exist

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

换句话说,您想要的是这样的逻辑,即消息的顺序不会改变最终结果,并且第一个写入者会赢得策略(又名比较和交换),这样当您有两个进程尝试时要更新相同的资源,数据竞赛的失败者必须重新开始。

作为一般规则,事件应该被理解为支持多个观察者 - 所有订阅者都可以看到所有事件。因此,除非您尝试跨多个进程分配特定订阅者,否则与竞争消费者的队列不是通常的方法。

【讨论】:

    【解决方案2】:

    您没有可以解决的并发问题。这完全归结为使用不良工具或不阅读文档。

    他们都听一个事件队列。

    该队列应该支持这一点。示例是 azure 队列,我可以在其中收听并告诉队列在 X 秒内不要向其他任何人显示该事件(这足以让我决定是否处理它)。如果我不回答 -> 在那之后重新插入事件。如果我先杀了它,就没有并发了。

    因此,您需要一个可以处理此问题的后端队列。

    【讨论】:

    • 好的,例如,如果我们谈论的是 ServiceBus 队列。我侦听该队列的服务有 2 个实例。当第一个实例正在处理“创建”事件时,第二个实例将获得“更新”事件并且无法执行此命令,因为它无效。对吗?
    • 说实话,您的 cmets 并没有增加太多价值。您能否推荐一下如何制作,例如,servicebus queue 确保其项目将由同一个服务实例处理?
    • 是的。聘请建筑师——您的服务设计时并未考虑到现实。更好?
    • 我可以说,如果您是建筑师,我们可能不会雇用您,谢谢,再见。
    • 没关系。看,我现在忙于工作多年。我从来没有被录用过。
    猜你喜欢
    • 2022-04-16
    • 1970-01-01
    • 2016-07-12
    • 2017-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-28
    相关资源
    最近更新 更多