【问题标题】:Akka routing actor when the routee wants to change the routing当 routee 想要更改路由时的 Akka 路由参与者
【发布时间】:2013-06-29 22:18:10
【问题描述】:

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

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

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

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

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

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

【问题讨论】:

  • 问题,每个要处理的事件/消息是否都有一个 ID 以及您的应用程序是否可以明确地说我有消息 ID=A 我需要消息 ID=B?根据您当前的设计,也许您有一个聚合器,它维护一个 ID 列表,并了解潜在的副作用并在需要时将消息转发给其他参与者。另一种选择是尝试尽可能多地对管道进行分组,以便向有限数量的参与者进行广播,并且参与者链自己决定下一步将消息发送到哪里。
  • @NightWolf 新的 akka 软件是一个聚合器,它的工作是制定业务规则来确定哪些消息是相关的并对其采取行动。因此,在将消息发送给规则参与者之前,不能将问题简化为知道哪些消息是相关的。事件的峰值突发量将非常高,因此需要扇出管道。路由参与者应该保存一个索引,哪些规则正在通过消息上的哪些业务键跟踪哪些消息。那么挑战就如问题中所述:如何有效地让路由更新该索引。
  • 我不确定我是否完全理解您为什么需要一个路由参与者。听起来 RuleActorX 正在做出需要更改路由状态的决定。对我来说,这听起来像是丰富。如果 RuleActorX 决定它需要更多数据,那么它应该通过向某个重新路由器发送消息来请求这一点,或者明确地从存储中获取消息。也许您可以使用代理来管理状态更改,而不是缓冲似乎有风险的消息。
  • 您是正确的,当我们更改他们希望看到的内容时,规则参与者当前会转到 mongodb 获取数据。我有一个 akka 解决方案,它在正常的持续查询模式下工作,但我们希望扩大规模以处理数千万或数亿条消息,因此正在寻找一个更实时的内存中事件流处理模型,具有最少的 io。我的问题是 akka 或 actor 模式来执行“实时连续查询,其中下游参与者有上游参与者以零 io 更改路线”。
  • 类似于 LRU 缓存的东西?

标签: akka


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 2018-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-16
    • 2020-09-05
    • 2020-03-02
    • 2021-12-10
    • 2016-02-10
    相关资源
    最近更新 更多