创建一个监管策略
来源:互联网 发布:mmd模型制作软件 编辑:程序博客网 时间:2024/05/06 09:49
以下更加深入地讲解错误处理的机制和可选的方法。
为了演示我们假设有这样的策略:
import akka.actor.OneForOneStrategyimport akka.actor.SupervisorStrategy._import akka.util.duration._ override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) { case _: ArithmeticException ⇒ Resume case _: NullPointerException ⇒ Restart case _: IllegalArgumentException ⇒ Stop case _: Exception ⇒ Escalate}
我选择了一种非常著名的异常类型来演示监管和监控 中描述的错误处理方式的使用. 首先,它是一个一对一的策略,意思是每一个子actor会被单独处理(多对一的策略与之相似,唯一的差别在于任何决策都应用于监管者的所有 子actor,而不仅仅是出错的那一个). 这里我们对重启的频率作了限制,最多每分钟能进行 10 次重启; 所有这样的设置都可以被忽略,也就是说,相应的限制并不被采用, 留下了设置重启频率的绝对上限值或让重启无限进行的可能性。
构成主体的 match 语句的类型是 Decider, 它是 PartialFunction[Throwable, Directive]. 这一部分将 子actor的失败类型映射到相应的指令 .
缺省的监管机制
如果定义的监管机制没有覆盖抛出的异常,将使用上溯 机制.
如果某个actor没有定义监管机制,下列异常将被缺省地处理:
ActorInitializationException 将终止出错的子 actor
ActorKilledException 将终止出错的子 actor
Exception 将重启出错的子 actor
其它的 Throwable 将被上溯传给父actor
如果异常一直被上溯到根监管者,在那儿也会用上述缺省方式进行处理。
测试应用
以下部分展示了实际中不同的指令的效果,为此我们需要创建一个测试环境。首先我们需要一个合适的监管者:
import akka.actor.Actor class Supervisor extends Actor { import akka.actor.OneForOneStrategy import akka.actor.SupervisorStrategy._ import akka.util.duration._ override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) { case _: ArithmeticException ⇒ Resume case _: NullPointerException ⇒ Restart case _: IllegalArgumentException ⇒ Stop case _: Exception ⇒ Escalate } def receive = { case p: Props ⇒ sender ! context.actorOf(p) }}
该监管者将用来创建一个我们用来做试验的子actor:
import akka.actor.Actor class Child extends Actor { var state = 0 def receive = { case ex: Exception ⇒ throw ex case x: Int ⇒ state = x case "get" ⇒ sender ! state }}
这个测试可以用 测试 Actor 系统 (Scala) 中的工具来进行简化, 比如 AkkaSpec 是 TestKit with WordSpec with MustMatchers 的混合
import akka.testkit.{ AkkaSpec, ImplicitSender, EventFilter }import akka.actor.{ ActorRef, Props, Terminated } class FaultHandlingDocSpec extends AkkaSpec with ImplicitSender { "A supervisor" must { "apply the chosen strategy for its child" in { // 在此添加代码 } }}
现在我们来创建 actor:
val supervisor = system.actorOf(Props[Supervisor], "supervisor")
supervisor ! Props[Child]
val child = expectMsgType[ActorRef] // 从TestKit的 testActor 中获取答案
第一个测试是为了演示 Resume 指令, 我们试着将actor设为非初始状态然后让它出错:
child ! 42 // 将状态设为 42
child ! "get"
expectMsg(42)
child ! new ArithmeticException // 让它崩溃
child ! "get"
expectMsg(42)
可以看到错误处理指令完后仍能得到42的值. 现在如果我们将错误换成更严重的 NullPointerException, 情况就不同了:
child ! new NullPointerException // 更严重的崩溃
child ! "get"
expectMsg(0)
而最后当致命的 IllegalArgumentException 发生时子actor将被其监管者终止:
watch(child) // 让 testActor 监视 “child”
child ! new IllegalArgumentException // 破坏它
expectMsg(Terminated(child))
child.isTerminated must be(true)
到目前为止监管者完全没有被子actor的错误所影响, 因为指令集确实处理了这些错误。而对于 Exception, 就不是这么回事了, 监管者会将失败上溯传递。
supervisor ! Props[Child] // 创建新的子actor
val child2 = expectMsgType[ActorRef]
watch(child2)
child2 ! "get" // 确认它还活着
expectMsg(0)
child2 ! new Exception("CRASH") // 上溯失败
expectMsg(Terminated(child2))
监管者自己是被 ActorSystem 的顶级actor所监管的。顶级actor的缺省策略是对所有的 Exception 情况 (注意 ActorInitializationException 和 ActorKilledException 是例外)进行重启. 由于缺省的重启指令会杀死所有的子actor,我们知道我们可怜的子actor最终无法从这个失败中幸免。
如果这不是我们希望的行为 (这取决于实际用例), 我们需要使用一个不同的监管者来覆盖这个行为。
class Supervisor2 extends Actor { import akka.actor.OneForOneStrategy import akka.actor.SupervisorStrategy._ import akka.util.duration._ override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) { case _: ArithmeticException ⇒ Resume case _: NullPointerException ⇒ Restart case _: IllegalArgumentException ⇒ Stop case _: Exception ⇒ Escalate } def receive = { case p: Props ⇒ sender ! context.actorOf(p) } // 覆盖在重启时杀死所有子actor的缺省行为 override def preRestart(cause: Throwable, msg: Option[Any]) {}}
在这个父actor之下,子actor在上溯的重启中得以幸免,如以下最后的测试:
val supervisor2 = system.actorOf(Props[Supervisor2], "supervisor2") supervisor2 ! Props[Child]val child3 = expectMsgType[ActorRef] child3 ! 23child3 ! "get"expectMsg(23) child3 ! new Exception("CRASH")child3 ! "get"expectMsg(0)
0 0
- 创建一个监管策略
- 重写监管策略
- 通过一个真实故事理解SOA监管
- 通过一个真实故事理解SOA监管
- 通过一个真实故事理解SOA监管
- [转] 通过一个真实故事理解SOA监管
- 一个Android位置监管程序的开发全流程
- 一个项目:某省工商总局商品监管的系统维护
- 肖磊看市:剖析比特币交易所监管背后真相,为何取缔并非最佳策略
- Oracle创建索引策略
- Android中如何通过强制设备管理策略创建一个安全敏感的应用程序
- 系统升级的一个策略
- 选择一个分辨率策略
- Git之分支创建策略
- Git之分支创建策略
- Git之分支创建策略
- Git之分支创建策略
- C#/.net学习-14-一个socket监管客户端与服务端的小demo
- php tips
- 多线程时序控制
- Android学习第二天 --一个简单的Android项目
- CloudSim源码分析之-startSimulation()
- android 二维码 扫描,生成,竖屏
- 创建一个监管策略
- http返回状态码总结
- socketpair
- JVM内部原理
- JDBC(二)大结果集分页,批处理,学习
- 三句话影响人的一生
- phthon 第一天
- 第七天、第八天 深入案例:绘图系统
- ListView的使用