4

请注意,以下描述仅用于说明目的。问题是关于 akka 中事件流处理的模式,而不是关于如何用替代设计解决说明性示例的问题。

想象一个用 Akka 编写的复杂事件处理引擎,其中事件规则由参与者建模。消息的事件流类似于订单、订单中项目的履行、订单付款。业务规则参与者正在做一些类似于为客户开具发票并跟踪付款直到完成的事情。业务规则感兴趣的数据本质上是非常动态的,不可能知道哪些规则正在跟踪消息流的哪些部分。

可以天真地使用广播路由器风格的方法。所有业务规则参与者都会看到所有数据,如果他们跟踪的不是数据,他们会忽略该消息。然而,这将存在可扩展性问题,因为并非所有规则参与者都对所有数据感兴趣。这意味着使用哪些规则参与者通过消息中的复杂业务标识符跟踪哪些类型的消息的索引。然后我们只能向规则参与者发送他们正在寻找的数据。哪些消息发送到哪些参与者的这个索引会根据参与者内的业务规则而变化。从路由参与者的角度来看,routee 想要动态更改路由。

这就产生了时间问题。如果路由参与者的运行速度足够快以使许多路由保持忙碌,那么它将传递一个消息流,例如 {A,B,C},直到一个特定的路由收到消息 {A}。如果该路由然后决定它需要消息 {B},那么它将已经被路由到它的上游,但不会路由到最近发现它现在想要消息 {B} 已经看到消息 {A} 的路由的邮箱。修改后的路由只会在 {C} 之后的消息上生效,或者更可能在路由参与者开始处理来自特定路由的响应消息时更晚。

对此的一种解决方案是在路由参与者处缓冲消息。然后,如果路由改变了它对响应消息感兴趣的内容,那么路由参与者可以扫描旧消息的缓冲区并根据需要重新发送一些消息。这意味着需要大量代码来保持消息缓冲区尽可能小,以便能够尽可能高效地重新发送它们。我想知道是否有更标准的模式或更自然的方法来解决 Akka 中的动态路由?

[脚注:注释中描述的替代解决方案是使用消息缓存并让规则参与者命中缓存,但假设缓存必须非常大,强制 IO 或与主 jdbc 存储的两阶段提交所以假设如果可以避免的话,缓存是不可取的。问题是关于 akka 中的事件流模式,其中路由规则可以以高度动态的方式更改 - 上面对此类系统的大致描述已简化且仅用于说明目的。关键段落是关于消息流 {A,B,C} 并且具有读取的路由 {A} 决定它需要消息 {B},该消息已经由上游路由器分派。]

4

1 回答 1

0

这个问题似乎相当笼统。我在这里看到两个子问题

  1. 它可能受益于规则分解。如果可以创建“相关令牌”(客户 ID、初始订单 ID),那么一些中间参与者可以进行非常好的初始路由(例如,基于令牌的哈希)。最后,最终参与者可以从更小的消息集中选择它需要的内容。

  2. 为了构建具有复杂规则的通用事件处理拓扑,可以考虑使用库SynapseGrid。它有一个构建器,用于构建拓扑,然后将其转换为互连参与者的运行时系统。这些规则要么像 Scala 函数一样简单,要么像具有嵌套参与者的完整子系统分支一样复杂。

于 2013-08-09T06:52:20.250 回答