同步关注点的事件溯源

Posted

技术标签:

【中文标题】同步关注点的事件溯源【英文标题】:Event sourcing for synchronous concerns 【发布时间】:2020-02-25 16:46:55 【问题描述】:

我很难理解如何使用可以支持同步请求的事件源来设计事件驱动的后端。据我了解,要利用事件溯源,您必须开发系统以对事件做出反应,以便在必要时可以重播它们以重新创建您的状态。为此,这意味着我们正在尝试解耦事件触发器和事件处理程序。

如果我们假设客户端发送请求以更新某些数据,我们如何在使用事件驱动系统时适应这种同步请求/响应模型?您是否说以下步骤是以事件驱动的方式处理请求的正确方法:

    在 API 网关或网络边缘的某些服务接收网络请求,并发出表示该请求的事件。此时 API 网关会挂起等待。

    发出的事件被事件存储捕获并记录

    具有处理更新的业务逻辑的服务在订阅事件存储时捕获事件。如果它能够处理更新,则生成成功事件;如果无法处理,则生成错误事件。

    API 网关接收它等待的成功或错误事件之一,最后将响应发送回浏览器。

我认为上述方法可以很好地分离关注点,但我怀疑这是否是通过接受来自外部客户端的请求的系统启用事件溯源的方式。

【问题讨论】:

【参考方案1】:

您混淆了几个术语和想法,这些术语和想法必须分开。一旦你在脑海中分离了这些,一切都应该清楚了。

事件溯源和事件驱动架构是两种不同的想法。事件溯源意味着您将对实体的所有更改保存在事件存储中,并获取该实体的当前状态,您可以将所有事件相加。这个概念涉及状态的存储,而不是请求的处理。我认为您在这个问题中所指的是事件驱动架构。将这些想法分开的必要性很快就会变得清晰。

在事件驱动架构中,有两个想法需要分开。有来自 UI 或外部系统的请求对数据进行一些更改;这是一条消息或请求。消息处理程序(在 CQRS 中通常称为命令)处理请求并以无效为由拒绝或对系统中的实体进行适当的更改。然后将这些实体的更改作为事件存储在事件存储中。 Event Store 中的事件应该只包含发生变化的数据,而不是实体的所有属性。如果命令更改了多个实体,则会将多个事件写入事件存储。

系统可以有事件存储的侦听器(或订阅者),并且可以启动其他业务逻辑以响应实体的变化。这些更改以最终一致的方式异步运行。

考虑到所有这些,我们可以讨论事件驱动架构如何处理同步和异步事件。请记住,EDA 是为异步处理和最终一致性而设计的,因此使其同步需要一些额外的工作。

使用上面的 4 个步骤,我们得到了这个

第 1 步:不更改描述的逻辑。网关收到请求(不是事件)并等待。

第 2 步:一些开发人员喜欢存储传入的请求以进行模式分析等,但不一定要成功处理请求。

在最终一致的架构中,业务逻辑将对传入请求进行一些基本验证,如果看起来不错,则发回操作成功的确认。该请求将被放入队列并在方便时进行处理。如果遇到错误,稍后会通知用户。

但由于您的系统是同步的,API(您称之为“API 网关”)将直接调用负责处理业务逻辑的服务——命令。

第 3 步:请求由命令处理,验证请求并对实体进行任何必要的更改。为所有实体更改创建事件(每个实体一个事件)。

第 4 步:该命令将成功或失败值同步返回给 API,API 将其返回给调用者。请注意,这应该是一个 async/await 调用,而不是来自 API 的阻塞调用。对于 API 和用户来说,它仍然看起来像一个同步过程。

【讨论】:

感谢您的回复,抱歉回复晚了。您的回答很好,但我对您提出的事件建模有疑问。您为什么建议我们为每个要更改的实体创建多个事件?如果我们这样做,我们的“事件”将是 CRUD 操作而不是重要的业务事件。它似乎是在响应式代码库中伪装自己的命令式代码。你有答案吗? 这些想法中的术语令人困惑,因为它们使用同一个词来表示两个截然不同的想法。事件溯源中的事件只是对实体所做的一组更改 - 只是 CRUD 操作。其目的是稍后通过将所有随时间的变化相加以达到实体的当前状态来重新创建该实体。事件溯源中的事件不反映进行更改的业务原因,仅反映进行了更改。 事件驱动架构中的事件是根据业务规则对某事进行更改的请求。本次活动将嵌入商业理念和目标。 EDA 中的事件由命令处理,该命令对实体进行必要的更改,从而生成事件溯源事件。我通常将 EDA 事件称为“请求”,以便将其与 ES 事件区分开来,但不幸的是,我无法决定世界称其为什么。 表达域事件然后产生事件源事件似乎是多余的。还发现很多资料说 Even Sourcing 事件和 Domain 事件是一回事。 我认为领域事件@alaboudi 是指与业务领域相关的事件。比如“下单”。我不认为它们只存在于内存中。linkedin.com/pulse/…

以上是关于同步关注点的事件溯源的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 CQS 进行读写

译见 | 用 Docker,Spring Boot/Cloud 和 Axon CQRS/ES(事件溯源)来构建微服务

安全服务的一些思考

如何理解新准则的计量溯源性(看VIM的权威解释)

彻底搞懂JS事件中的循环机制 Event Loop

追溯溯源系统平台定制开发