scala - Akka + WithinTimeRange

标签 scala akka fault-tolerance

我已经测试了 akka 的容错系统,到目前为止,在谈论根据指定的 maxNrOfRetries 重试发送消息时,它一直很好。

但是,它不会在给定的时间范围内重新启动 actor,它会立即重新启动,忽略时间范围内的内容。

我尝试了 AllForOneStrategy 和 OneForOneStrategy 但没有改变任何东西。

尝试关注这篇博文:http://letitcrash.com/post/23532935686/watch-the-routees ,这是我一直在使用的代码。

class Supervisor extends Actor with ActorLogging {

  var replyTo: ActorRef = _

  val child = context.actorOf(
    Props(new Child)
      .withRouter(
        RoundRobinPool(
          nrOfInstances = 5,
          supervisorStrategy =
            AllForOneStrategy(maxNrOfRetries = 3, withinTimeRange = 10.second) {
              case _: NullPointerException     => Restart
              case _: Exception                => Escalate
            })), name = "child-router")

  child ! GetRoutees

  def receive = {
    case RouterRoutees(routees) =>
      routees foreach context.watch

    case "start" =>
      replyTo = sender()
      child ! "error"

    case Terminated(actor) =>
      replyTo ! -1
      context.stop(self)
  }
}

class Child extends Actor with ActorLogging {

  override def preRestart(reason: Throwable, message: Option[Any]): Unit = {
    log.info("***** RESTARTING *****")
    message foreach{ self forward }
  }

  def receive = LoggingReceive {
    case "error" =>
      log.info("***** GOT ERROR *****")
      throw new NullPointerException
  }
}

object Boot extends App {

  val system = ActorSystem()
  val supervisor = system.actorOf(Props[Supervisor], "supervisor")

  supervisor ! "start"

}

我做错了什么吗?

编辑

其实我误解了withinTimeRange的用途。 要在某个时间范围内安排我的重试,我正在执行以下操作:

override def preRestart(reason: Throwable, message: Option[Any]): Unit = {
    log.info("***** RESTARTING *****")
    message foreach { msg =>
      context.system.scheduler.scheduleOnce(30.seconds, self, msg)
    }
  }

它似乎工作正常。

最佳答案

我认为您误解了 withinTimeRange 参数的用途。该值应该与 maxNrOfRetries 结合使用,以提供一个窗口,在该窗口中支持限制重试次数。例如,正如您所指定的,这意味着如果某个 child 需要在 10 秒内重启超过 3 次,主管将不再重启该 child 。

关于scala - Akka + WithinTimeRange,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31877943/

相关文章:

scala - 如何避免scala的case类默认toString函数被覆盖?

java - 使用有界继承重写 Scala 中 Java 类的抽象方法

scala - 一些 ScalaTests 不能从 IDEA 运行 - NoSuchMethodError

java - Actor 与线程的定义有何不同?

scala - Akka 。如何知道所有 child Actor 都完成了他们的工作

spring-boot - 使用 Consul 集群实现容错

scala - Akka-Http 中的实体是什么?

java - JVM 的分布式故障安全作业队列

protocols - 如果 DHT 的某个节点发生故障,这些值是否会变得不可用?

scala - 发生崩溃时保持 Akka 状态