Akka:如何在延迟时间间隔越来越长的情况下安排失败重试?

时间:2012-04-28 14:56:22

标签: java error-handling akka akka-supervision

让一个演员在失败时再次尝试一些东西的好方法是什么,但重试之间的时间间隔越来越长?假设我希望演员在15秒后再尝试30秒,然后每分钟再尝试一次。

以下是我的想法:

  • 执行实际工作的actor的方法有一个可选项 RetryInfo参数,如果存在,则包含其编号 我们目前正在重试
  • 失败时,actor会发送一个新的ScheduleRetryMessageretryCount + 1,然后抛出一个RuntimeException
  • 另一名演员监督工人演员,使用new OneForOneStrategy(-1, Duration.Inf()返回Resume作为其指令。演员没有状态,所以Resume应该没问题
  • 收到ScheduleRetryMessage后,演员会
    • if retryCount < MAX_RETRIES:使用Akka的计划程序安排在所需的延迟后发送RetryMessage
    • else:最后放弃,向另一位演员发送错误报告

这是一个很好的解决方案还是有更好的方法?

2 个答案:

答案 0 :(得分:8)

你可以有一个主管来启动工人演员。文档的提示是为工作者声明一个大小为1的路由器。主管将跟踪重试次数,然后根据需要安排发送给工作人员的消息。

即使你要创建另一层演员,这对我来说似乎更清晰,因为你会将监督功能保留在工作人员之外。理想情况下,你可以让这个1个主管给n个工人,但我认为你必须使用生命周期监控从儿童演员那里获得失败。在这种情况下,您可以保留[ActorRef,Int]的地图,以跟踪所有受监管工人的重试次数。监督政策将恢复,但如果您达到最大重试次数,则可以将PoisonPill发送给违规的ActorRef。

答案 1 :(得分:7)

在这种情况下,我使用标准监督。 父/监督角色定义时间窗口内的重试。 重试工作者孩子只需重新安排导致失败的消息,并在preRestart()中延迟。

如果重试子项相当复杂,您可以考虑互连一个中间actor。 那个演员只是升级了监督。 在preRestart上,中间actor调度(延迟)重启消息。 当中间actor保持其状态时,它可以简单地重新启动worker actor(延迟)。

正如您所看到的,延迟部分可能位于preRestart或工作人员的开始。