一. 创建一个监控策略
-
策略的选择
-
one-for-one strategy
: 每个actor被单独处理 -
all-for-one strategy
: 任何监控动作都作用于被其监控的所有actor
-
-
策略的动作是一个偏函数
这个偏函数是PartialFunction[Throwable, Directive]
; 其参数是Throwable
, 输出是Directive
- 自定义一个策略
import akka.actor.OneForOneStrategy import akka.actor.SupervisorStrategy._ import scala.concurrent.duration._ override val supervisorStrategy = // 下面的2个参数表示: 如果1个actor在1分钟之内重启次数超过10次, 该actor就会被停止 OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) { case _: ArithmeticException => Resume case _: NullPointerException => Restart case _: IllegalArgumentException => Stop case _: Exception => Escalate // 对于策略无法覆盖到的异常, 可以使用默认的 }
- maxNrOfRetries与withinTimeRange的解释
-
maxNrOfRetries=-1, withinTimeRange=Duration.Inf
: 表示无限制的重启子actor -
maxNrOfRetries=-1, withinTimeRange=非无限的一个时间段
: 按照maxNrOfRetries= 1
处理 -
maxNrOfRetries=1个非负数, withinTimeRange=Duration.Inf
: 表示子actor只要重启次数超过maxNrOfRetries, 则子actor就会被停止
-
-
默认监控策略
-
Escalate
用于当actorref抛出策略未覆盖到的异常时, 采取的默认方法;
默认情况下, 父actor会重启子actor - 默认的监控策略为
akka.actor.DefaultSupervisorStrategy
是一个OneForOneStrategy
, 其偏函数定义为若策略未对以下异常做出声明, 则采用默认行为:-
ActorInitializationException
will stop the failing child actor -
ActorKilledException
will stop the failing child actor -
DeathPactException
will stop the failing child actor -
Exception
will restart the failing child actor -
Other types of Throwable
will be escalated to parent actor
-
- 可以组合自己的监控策略和已有的监控策略:
import akka.actor.OneForOneStrategy import akka.actor.SupervisorStrategy._ import scala.concurrent.duration._ override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) { case _: ArithmeticException => Resume case t => super.supervisorStrategy.decider.applyOrElse(t, (_: Any) => Escalate) }
-
二. 顶级Actor的监控策略
顶级actor是使用system.actorOf()
创建的actor, 是被/user
守卫的; 这些actor的监控策略使用配置的策略
三. actor的生命周期
上图是官网中, 关于actor生命周期的展现:
- actor是一个有状态的资源, 需要被显式的start和stop
关闭一个父actor, 会递归的关闭其创建的所有子actor; 同样, 停止一个actorsystem, 也会停止下面的所有actor - 重启一个actor, 其关联的子actor也会重启
-
actor
是被path
和一个uid
唯一标识的 - 对于Restart的监控做法,
preRestart
在老actor上调用,postRestart
在新actor上调用
网友评论