【问题标题】:How to terminate a hung akka actor?如何终止挂起的 akka 演员?
【发布时间】:2014-07-11 10:13:36
【问题描述】:

我正在为 Akka 编写 HelloWorld,我已经在 Main Actor 中创建了固定(20 到 50)个 Actor,其中一半是简单的计数器,另一半计算阶乘并以某种方式求和结果。 主要目标是测试 Akka 如何处理顽皮的挂起线程。我将具有半随机时间的 Thread.sleeps 添加到我的线程中,并通过安排特殊的 ForceShutdown 案例来定义超时。

想要得到什么:

  • 1) 主要参与者接收 StopMessage,从以下位置收集结果 儿童演员并给他们PoisonPill
  • 2) 收集完所有结果后,主要 Actor 关闭 系统
  • 3) 如果在超时期间未收集结果,则 ForceShutdown 案例正在启动,杀死一切并关闭 强制系统。

我得到了什么: 1 和 2 工作正常,但是:

  • 3) 一旦 ForceShutdown 被触发,MainActor 仍在等待 孩子们完成他们的工作,这不会终止他们。

我尝试了几种 ForceShutdown 案例的变体,但大多数都一样,等待子演员完成未完成的工作。 这是一个例子:

case ForceShutdown =>
  println(s"[${self.path.name}] ForceShutdown received!")
  children foreach { child => system.stop(child) }
  system shutdown

那么,如何在 Akka 中强制终止挂起的演员?

【问题讨论】:

  • 在actor模型中,你不会终止某人,而是请某人停下来。这就是您的代码不起作用的原因——相关摘录from the doc当前消息的处理(如果有)将在actor停止之前继续,但不会处理邮箱中的其他消息.. . 如果其中一个actor没有响应(即长时间处理消息,因此没有收到停止命令),整个过程就会卡住.
  • 所以,你的actor被锁定在处理当前消息并且它不知道有人想要它停止。不过,不知道如何强迫它。顺便说一下YDIW by spawning actors solely to send off actual processing,除非他们执行一些分阶段的处理。
  • 感谢您的评论,尽管我敢打赌这应该是一个答案。所以,如果有一个挂起的actor,就没有办法关闭应用程序。我想到了一个简单的解决方案:如果actor内部的某些处理存在危险,我可以用Future/Await包装它,它有超时。这样我就可以保证没有演员会被绞死。我应该试试看。

标签: scala akka actor


【解决方案1】:

在 JVM 上,没有办法强制关闭任何东西,因为在同一进程中终止某些东西可能会破坏共享状态并导致应用程序损坏。您对 Future 的想法一开始似乎可行,但运行失控代码的线程池不会关闭,这意味着 JVM 不会停止或将累积失效的线程池并最终耗尽内存。

因此,您应该设计所有 Actor 以保持响应:如果您需要运行长时间的处理任务,您应该将它们分解为 Actor 发送给自己的短步骤。这样,终止请求将在适当的时候得到兑现。

【讨论】:

    【解决方案2】:

    akka 是完全异步的进程。甚至Kill 消息也需要等到当前任务完成。只是Kill 具有最高优先级,因此邮箱排队的消息将被忽略,而PoisonPill 就像普通消息一样,将被最后处理。所以必须在actor关闭之前优雅地处理排队的消息。

    【讨论】:

      猜你喜欢
      • 2018-12-15
      • 2018-04-20
      • 1970-01-01
      • 1970-01-01
      • 2017-05-29
      • 1970-01-01
      • 2019-01-01
      • 2014-12-02
      • 2020-05-13
      相关资源
      最近更新 更多