Akka 在容错方面有如下特点:
Akka 对于错误的观点值得称道:没有银弹,应该着眼于如何进行灾后重建
和传统应用将业务逻辑 和 try {} catch{}
错误处理绞在一起不同,Akka 的容错恢复是独立于业务逻辑的:Actors专注于自己的消息处理逻辑,而错误处理和策略设定,则由层 级结构里,它的监督者(父级Actor结点)来操心。
监督者(Supervisor)并不去catch子结点的错误,而是仅决策子结点该如何恢复:
在一个策略中,应对子结点错误,我们有四个选项进行响应:
系统内置了两种策略:
我们也可以自定义结点的策略:OneForOneStrategy 是仅响应出错结点的策略,AllForOneStrategy 策略则是响应影响所有的子结点。
在一个Actor系统中,Supervisor收到 spawn
消息就创建Worker子结点,当这些Worker遇到不同的错误时,Supervisor 将使用一对一策略进行不同的响应:
import scala.concurrent.duration._ import akka.actor.{Actor, ActorLogging, ActorSystem, OneForOneStrategy, Props} import akka.actor.SupervisorStrategy._ class Supervisor extends Actor with ActorLogging { override def receive: Receive = { case "spawn" => context.actorOf(Props[Worker]) } override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 30 seconds) { case _: ArithmeticException => Resume case _: NullPointerException => Restart case _: IllegalArgumentException => Stop case _: Exception => Escalate } } class Worker extends Actor with ActorLogging { override def receive: Receive = ??? } object StrategyApp extends App { implicit val system = ActorSystem("actor-system") import system.dispatcher system.actorOf(Props[Supervisor], "supervisor") }