流式事件和基于规则的触发器

Streaming events and rule based trigger

鉴于 Event-AEvent-BEvent-C 在几天之内到达(可能出现故障),我想触发处理以生成导数 Event-ABC一旦我知道我拥有所有事件。

事件按 userId/sessionId

分组

目前我从一个队列中读取所有事件,写入数据库,并更新元数据以说明哪些事件已被写入。一旦元数据包含基于规则的所有事件,我就会触发聚合处理。这种方法存在一些性能问题,因为队列工作人员在处理属于同一组的事件时可能会敲击相同的键,因此我正在寻找替代方案。

我想要的是基于 userId/sessionId 处理的更细粒度的软件定义路由和排队事件。我认为我正在尝试做的事情有点类似于事件溯源。

我正在研究 Akka 是否可以帮助解决此类问题。对于每个 userId/sessionId 一个 actor,它将减少不需要的并发并在 actor 中包含触发逻辑。我担心的是使用如此多的 Actors 时可能需要大量内存。

与事件溯源相比,您所描述的更类似于 Saga 或流程管理器。您需要能够处理多条消息然后在满足规范后做出反应的东西。

Akka 完全可以应对。使用 Akka,您可以为每个键创建一个 actor,然后在收到消息时将消息路由到各个 actor。我不会太担心内存问题,因为 Actor 系统应该可以处理成千上万的 Actor。我认为您需要衡量您获得的任何解决方案的性能。

您还需要考虑如何处理服务器崩溃 - 如果您将所有内容都保存在内存中,那么当服务器崩溃时您很容易丢失您的 sagas。这可能是也可能不是问题,具体取决于您的要求(即,如果您可以从中恢复)。如果考虑到这一点很重要,您可以查看 Akka Persistence。

This approach has some performance issues due to queue workers potentially hammering the same key when processing events that belong to the same group, so I am looking for alternatives.

免责声明:我不确定我是否理解您在这里描述的内容,因此下面的解决方案可能不合适。

I think what I am trying to do is somewhat similar to event sourcing.

是的,您的描述听起来很像事件来源 process manager

事件处理程序(您可能对每种事件类型都有一个处理程序,或者一个订阅所有这三种事件的处理程序)接收一个事件。

根据 userId/userSession 信息,它会为您的进程的这个实例计算一个唯一标识符。想想哈希,或命名为 uuid,从进程的唯一标识符构建。

加载与标识符匹配的进程的当前状态。这是一个数据结构,用于跟踪以前见过哪些事件。它可能只是一个事件流。

apply当前事件到进程状态。如果已经看到此事件,"apply" 应该是空操作 -- 您的事件消息确实具有唯一标识符,对吗?

保存更新的进程状态。交易结束。

现在观察进程状态 -- 您可以在事件处理程序或异步进程中立即执行此操作。如果过程是"ready",那么产生Event-ABC的动词。

上面的概述遵循常见模式,其中流程管理器跟踪 运行 流程的状态,但通过针对适当聚合的 运行 命令触发业务逻辑。

在更简单的设计中,您可以组合使用 "the aggregate" 和 "the process"。基本模式是相同的——事件处理程序计算聚合的 id,加载它,并调用处理事件命令。聚合使用事件中包含的信息更新自己的状态,并将该状态更改写入自己的历史记录。如果考虑了所有必需的事件,聚合也会将事件 ABC 写入其自己的历史记录中。