10

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

这是我想出的:

  • 执行实际工作的actor的方法有一个可选 RetryInfo参数,如果存在,它包含我们当前的重试次数
  • 失败时,actor 将向自己发送一个新ScheduleRetryMessage的 with retryCount + 1,然后抛出一个 RuntimeException
  • 另一个演员监督工人演员,使用new OneForOneStrategy(-1, Duration.Inf()返回Resume作为其指令。演员没有状态,所以Resume应该没问题
  • 收到后ScheduleRetryMessage,演员将
    • if retryCount < MAX_RETRIES:使用 Akka 的调度程序来安排RetryMessage在所需延迟后发送
    • else: 最终放弃,发送消息给另一个actor进行错误报告

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

4

2 回答 2

9

在这种情况下,我使用标准监督。父/监督参与者定义时间窗口内的重试。重试工作子进程只是重新调度导致失败的消息,并在 preRestart() 中延迟。

如果重试的孩子相当复杂,您可以考虑互连一个中间参与者。那个演员只是升级监督。在 preRestart 中,中间参与者会安排一个(延迟的)重启消息。由于中间actor保留了它的状态,它可以简单地重启workeractor(有延迟)。

正如您所看到的,延迟部分可能在 preRestart 或 worker 启动时。

于 2012-12-13T09:52:49.397 回答
8

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

即使您将创建另一层演员,这对我来说似乎更干净,因为您会将监督功能排除在工作人员之外。理想情况下,您可以将这 1 个主管设置为 n 个工人,但我认为您必须使用生命周期监控来从子角色那里获得失败。在这种情况下,您可以只保留 [ActorRef, Int] 的地图来跟踪所有受监督工作人员的重试次数。监督策略会 Resume,但如果您达到最大重试次数,您可以向违规的 ActorRef 发送 PoisonPill。

于 2012-04-30T05:36:49.883 回答