繁体   English   中英

Akka Java容错和actor重启

[英]Akka Java fault tolerance and actor restarting

我目前正在研究Akka(Java版)中的Fault Tolerance和Supervisor策略。

at ... http://doc.akka.io/docs/akka/2.3.2/java/fault-tolerance.htmlhttp://doc.akka.io/docs/akka/2.3.2/general/ supervision.html#监督

几个问题:

1)当我们知道期望什么样的例外时,我们是否应该在演员中使用try / catch块? 为什么或者为什么不? 如果没有,我们是否应该依靠主管策略来有效处理孩子可能抛出的异常?

2)默认情况下,如果在父actor中没有显式配置管理程序,则默认情况下将重启任何抛出异常的子actor。 如果整个系统中的所有演员都没有状态怎么办...我们真的应该重启吗?

3)如果由system.actorOf(...)创建的顶级actor会引发异常怎么办? 你如何在演员系统之外提供监督策略?

4)让我们假设一个场景,其中演员A有一个儿童演员B.现在让我们说演员A要求演员B做一些工作。

有些代码可能如下所示:

Future<Object> future = Patterns.ask(child, message, timeout);
future.onComplete(new OnComplete<Object>() {

    @Override
    public void onComplete(Throwable failure, Object result) throws Throwable {
             ... handle here    
    }

现在......如果演员A以某种方式抛出异常会怎样。 默认情况下,它由主管重新启动。 问题是,onComplete“闭包”是否仍会在将来的某个时间执行,还是在重启时有效“消失”?

5)假设我有一个层次结构,如:A-> B-> C. 我们也假设我覆盖preRestart,这样我就不会阻止我的孩子。 在A的预启动时,他调用getContext()。actorOf(B),并在B的预启动中调用getContext()。actorOf(C)。 如果A抛出异常,系统中是否会存在多个actor B和多个actor C?

谢谢!

这将是一个很长的答案,但让我尽可能有序地解决你的观点。
此外,我将依赖官方Akka文档,因为我相信Akka是最好的文档项目之一,我不想重新发明轮子。 :)

  1. 对Akka中容错工作方式的一个很好的介绍/概述是[1] 我认为这篇文章很好地总结了几页Akka文档。 为了特别回应这一点,我认为这取决于:你可以try/catch异常,当然,但是错误内核模式声明你应该“ 压低actor层次结构 ”任何可能失败的东西(这是为了防止或限制尽可能多的尽可能在演员中失去国家)。 这就是说,如果你有一个非常具体的Exception并且你知道如何处理它作为处理消息的一部分,我认为捕获它没有任何内在问题。 实际上,我至少可以想到一个特殊情况,你捕获异常并处理它们:如果你的actor正在响应Pattern.ask ,你需要在Failure包含异常,如果你想要通知调用者。 [2] )。

  2. [3]中所述,默认行为确实是Restart ,但仅在消息处理期间抛出Exception情况下。 请注意,默认情况下, ActorInitializationExceptionActorKilledException终止ActorKilledException ,并记住在preStart抛出的任何Exception都将包装在ActorInitializationException 至于Restart是否是声音默认“万一你的演员没有状态”......好吧,根据定义,一个演员是一个在并发环境中安全访问和操纵状态的抽象:如果你不喜欢没有状态,你可能也可以使用Future而不是演员。 通常,对于典型用例, Restart被视为安全且合理的默认设置。 在您的特定情况下(这不是演员系统的典型用例),您无论如何都可以覆盖默认监督策略。

  3. 顶级角色仅从“ 用户 ”的角度来看是顶级的。 [4]中所述 ,任何顶级actor都是作为Guardian actor的子级创建的,它具有正常的默认监督策略。 此外,您可以使用属性akka.actor.guardian-supervisor-strategy修改此类默认值。 另外,请记住,你应该始终设计你的系统,记住Akka的层次性( [5] ),因此不要过多地使用顶级演员( [6] )。

  4. 是否调用onComplete的回调取决于A何时失败。 如果 B完成并且响应A的请求失败,那么它可能会执行。 否则它不会。 使用旧的A实例时,它会“消失”。

  5. 这有点令人困惑,但我会假设如下:

    • 当你说“ A抛出异常”时,你的意思是在消息处理中( onReceive
    • 你的actor中有一个字段,用于存储getContext().actorOf(C)返回的ref。

快速回答是: 是的 根据您描述的场景,将有多个BC实例。 然而, A的新实例不会知道。 它将引用新的B并间接引用新的C 这是合理的,也是预期的,因为您手动明确地禁用了一个处理actor层次结构中的失败的默认清理逻辑(通过更改postRestart ):现在您有责任进行清理,并且您描述的preStart实现不会这样做。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM