【问题标题】:Message Persistence and Playback with restarted actors in Akka在 Akka 中使用重新启动的 Actor 进行消息持久性和回放
【发布时间】:2015-08-25 21:21:20
【问题描述】:

Akka Java 在这里。我有两个演员,ParentChild,前者是后者的父级。如果Child 抛出一个特定的异常(比如UnrulyTeenagerExcepton),那么我正在寻找的行为如下:

  • Parent 保存了对抛出异常时Child 正在处理的消息的引用;那么
  • Child重启,持久化消息“回放”到Child;但是
  • 如果此保存 -> 重新启动 -> 重播循环发生 3 次,Child 抛出 UnrulyTeenagerException 3 次,那么我们 SupervisorStrategy.escalate()

迄今为止我最好的尝试:

// Groovy pseudo-code
class ChildFailureDecider extends Function<Throwable,Directive> {
    int maxRetries = 3
    int numRetries = 0

    @Override
    Directive apply(Throwable childFailure) {
        if(childFailure instanceof UnrulyTeenagerException) {
            numRetries++

            if(numRetries <= maxRetries) {
                // TODO: #1 How to persist the message that caused the ‘childFailure’?

                return SupervisorStrategy.restart()

                // TODO: #2 How to ‘play back’ the persisted message to Child?
            }
        }

        SupervisorStrategy.escalate()
    }
}

但正如您所见,我正在为消息持久性和回放而苦苦挣扎。有任何想法吗? 非常感谢 Java 代码示例,Akka 足够强悍,无需学习 Scala 象形文字!

【问题讨论】:

  • 通过'persist',您是否需要将消息写入磁盘,或者只是在其被捕获在Parent内部的变量中的意义上持久化?
  • 感谢@mattinbits (+1) - 我所说的“持久”是指使用 Akka-Persistence 模块和UntypedPersistentActorWithAtLeastOnceDelivery 完成的任何事情。然而,诚然,我并不完全理解持久性参与者的工作原理,因此它们可能与我在这里展示的用例不同。归根结底,我只需要 Akka 保存(某处)在处理子进程时失败的消息,重新启动子进程,然后在重新启动的子进程上重新处理已保存的消息。想法?再次感谢!

标签: java akka akka-supervision


【解决方案1】:

Akka 持久性是关于以持久的方式(例如记录到磁盘或数据库)以持久的方式记录事件(与消息不同),以便在整个应用程序终止时(例如 JVM 崩溃或硬件失败),可以在重新启动时重建该参与者的状态。在您的情况下,您希望记住发送给单个演员的消息并在该演员因故障重新启动时重新发送,所以我认为在这种情况下您不需要持久性 API。

当参与者抛出异常时,该异常会呈现给主管,但导致异常的消息不会。我认为没有一种内置的方法可以实现这一目标。监督者可以通过设置适当参数的监督策略来管理只重启3次的规则:http://doc.akka.io/japi/akka/2.4-M3/akka/actor/OneForOneStrategy.html#OneForOneStrategy-int-scala.concurrent.duration.Duration-akka.japi.Function-

消息的重放需要由发送者处理。您可以通过让接收方在处理完消息后向发送方发送确认来实现至少一次语义,如果没有收到确认,则让发送方定期重试。有关更多信息,请参阅此问题:Akka Message Delivery Guarantees

很抱歉缺少代码,但我使用的是 Scala API 而不是 Java。

【讨论】:

  • 感谢@mattinbits (+1) - 这是有道理的。关于持久性actor,这里只是好奇,你想在什么样的用例下重建一个actor的确切状态?对我来说,这感觉很像event sourcing,我能想到的事件溯源参与者状态的唯一用例是用于解决生产问题。想法?再次感谢!
  • 这很像事件溯源,引用了 akka 持久性文档Akka persistence is inspired by and the official replacement of the eventsourced library :) 我不是用例方面的专家,在最简单的情况下,它可以为您的应用程序增加健壮性,因为状态可以在重新启动后幸存下来,但当然您可以使用常规数据库功能来实现这一点。但是事件日志允许您对系统历史执行分析,这在更多情况下很有用,而不仅仅是故障排除。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-27
  • 2016-03-07
  • 1970-01-01
  • 2018-01-14
  • 2016-10-22
  • 2013-02-20
相关资源
最近更新 更多