gpt4 book ai didi

cqrs - CQRS/事件源/事件总线/时序

转载 作者:行者123 更新时间:2023-12-02 06:52:50 30 4
gpt4 key购买 nike

我的CQRS / ES设计中有时间问题。为了便于讨论,让我们基于Microsoft的
有关此主题的示例, session 管理(https://msdn.microsoft.com/en-us/library/jj554200.aspx)。

两种情况: session 管理和订单管理。在 session 管理中,您可以创建 session 并更改其属性(例如,最大席位)。 session 管理通过事件总线与订单管理进行通信。通过这种方式,订单管理知道何时创建新 session ,并在其上下文中实例化跟踪对象(席位可用性)。诸如“最大席位可用性从100减少到80”之类的事件也通过事件总线从conf mgmt传达给mgmt。

  • 假设在第一分钟创建了 session (最多20个席位)。
  • 在第4分钟,事件到达订单mgmt上下文,因此创建了席位。
  • 在第7分钟,用户下了订单(通过订单管理),购买了全部20个席位。 (这也应该从-订单管理传达到conf管理,以便conf admin可以做出正确的决定)。
  • 在第8分钟,conf admin更改了席位可用性(在conf mgmt上下文中),将其减少到15。
  • 来自订单mgmt的通知(关于所有20个席位已售出的事实)在第9分钟到达。
  • 现在该怎么办? (在conf mgmt上,当您已经收到20的付款时,您不应该将座位减少到15;但是在第8分钟,管理员对此一无所知)。

  • 那是第一种情况。

    现在第二种情况:
  • 假设在第一分钟创建了 session (最多20个席位)。
  • 在第4分钟,事件到达订单mgmt上下文,因此创建了席位。
  • 在第6分钟,conf admin更改了席位可用性(在conf mgmt上下文中),将其减少到15。
  • 在第7分钟,用户下了订单(通过订单管理),购买了全部20个席位。他不知道可用性是否已降低到15,因为该事件尚未到位。
  • 在第10分钟,来自conf mgmt的通知终于到达了。
  • 现在该怎么办?

  • 这些问题源于技术问题(事件传输的延迟)。有没有纯粹的技术方法可以避免这种情况?
    如果没有,克服它的业务方式/设计方式是什么?

    补充说明:我知道这是与CQRS / ES架构有关的最终一致性问题。在单个上下文中,这可能更容易解决,因为您可以为此使用 命令(例如undo)。但是,在有限的上下文之间,您不应传递命令,而只能与事件进行通信,而且我认为事件不是对此的正确抽象(因为它表示发生的事情)。还是我错过了什么?

    补充说明:也许本文可以为解决方案提供更多的背景信息和提示,但是对于这个问题中的这种特定情况,我认为不是这样(这与乱序消息无关)。 http://blog.jonathanoliver.com/cqrs-sagas-with-event-sourcing-part-i-of-ii/

    补充说明:或者……在订单管理上下文中,我们可以简单地将购买座位的命令排队,直到我们知道从 session 管理上下文中接收到最新/最新事件。我的意思是,事件带有时间戳,对吗?因此,我们可以将从conf mgmt上下文接收到的最后一个事件的时间戳与购买座位命令的时间戳进行比较。如果最后一个事件的ts小于命令的ts,则我们只是推迟执行该命令,直到收到一个ts大于命令的ts的事件。这种事情将是流程经理(传奇)的责任。

    那行得通吗?这是正确的方法吗?

    添加了注释:相关线程> Implementing a Saga/Process Manager in a CQRS http application。我认为我们与流程经理的关系是正确的。正如回答者所说:“您根本不会立即回答“已确认订单”。看看亚马逊和其他购物网站是如何做到的:提交订单后,您只会收到“已接受订单确认(例如,接受HTTP代码202) )。”。

    由流程管理器的逻辑决定何时实际执行命令(基于某些条件,内部状态,或者在这种情况下,是从其他上下文中收到的最新事件)。

    有什么意见吗?

    谢谢,
    拉卡

    最佳答案

    三种可能性

    首先,您接受最终的一致性。如评论中所述,在许多最终的一致性场景中,事实证明,如果及时意识到问题,企业将有缓解问题的方法-因此,您需要采取一些措施来观察模型中的事件,从而注意到您在保留的座位数和售出的座位数之间存在差异,也许还有一个基于任务的UI,允许人类做正确的事[tm]。

    其次,与业务部门联系,以查看您是否在正确地对实际业务流程进行建模。例如,您可能在购买座椅时缺少几个阶段;订单管理人员可能需要在确认订单之前预留座位。

    (这就是说,一个客户想要20个席位的事件可能与说我们实际上将席位卖给她的事件是分开的,这与 session 管理已为该客户预留席位的事件不同。 )。

    请注意,这实际上并不能使您摆脱业务问题-您仍然想在想要购买20个席位的客户与想要减小观众人数的 session 组织者之间保持竞争状态。您得到的是一个稍微清晰的故障模式(如果客户赢得比赛以争取席位,那么 session 管理者可以拒绝减少计数。同样,如果组织者赢得比赛,则保留座位的尝试也将被拒绝)。

    这假定 session 管理部门应保持不变,即保留席位的数量应少于分配的席位。在您的业务中,这可能实际上并非如此。同样,能够跟踪客户尝试预订的座位数超过可用座位数的次数对于企业可能很有用。

    第三,可能是您的服务边界绘制在错误的位置。 Udi Dahan wrote

    Any piece of data or rule must be owned by only one service.



    如果 session 管理中的席位和订单管理中的席位是同一回事,那么也许它们属于同一服务边界(相同的服务边界)。

    我的建议是基于这样的原则,即在出现需求时自动化应该能够摆脱领域专家的阻碍,您应该主要考虑第一种方法-您可以浮出水面并放弃控制权吗?给业务专家。如果做得对,您可能会成功完成一个项目。

    关于cqrs - CQRS/事件源/事件总线/时序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39334288/

    30 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com