akka actor监控(monitoring)

来源:互联网 发布:中世纪2原版优化9血统 编辑:程序博客网 时间:2024/04/30 00:38

    在Akka中生命周期监控通常指的是DeathWatch。除了父actor和子actor的关系的监控关系,每个actor可能还监视着其它任意的actor。监视actor通过接收Terminated消息来实现生命周期监控。如果没有其它的处理方式,默认的行为是抛出一个DeathPactException异常。为了能够监听Terminated消息,你需要调用ActorContext.watch(targetActorRef)。调用ActorContext.unwatch(targetActorRed)来取消对目标角色的监听。需要注意的是,Terminated消息的发送与监视actor注册的时间和被监视角色终止的时间顺序无关。例如,即使在你注册的时候目标actor已经死了,你仍然能够收到Terminated消息。当监管者不能简单的重启子actor而必须终止它们时,监视将显得非常重要。例如,actor在初始化的时候报错。在这种情况下,它应该监视这些子actor并且重启它们或者稍后再做尝试。一个常见的应用案例是,一个actor或者它的子actor在无法获得需要的外部资源时需要失败。如果是第三方通过调用system.stop(child)方法或者发送PoisonPill消息来终止子actor时,监管者也将会受到影响。 

class WatchActor extends Actor {val child = context.actorOf(Props.empty,"child") context.watch(child)var lastSender = system.deadLettersdefreceive = {case "kill"⇒ context.stop(child)lastSender = sendercase Terminated(`child`) ⇒ lastSender !"finished"}}


注意:
1,Terminated 消息的产生与注册和终止行为所发生的顺序无关。多次注册并不表示会有多个消息产生,也不保证有且只有一个这样的消息被接收到:
如果被监控的actor已经生成了消息并且已经进入了队列,在这个消息被处理之前又发生了另一次注册,则会有第二个消息进入队列,因为一个已经终止的actor注册监控器会立刻导致 Terminated 消息的发生。


2,可以使用 context.unwatch(target) 来停止对另一个actor的生存状态的监控,但很明显这不能保证不会接收到 Terminated 消息因为该消息可能已经进入了队列。


较完整的代码实例:

import akka.actor.{PoisonPill, ActorSystem, Props}import com.typesafe.config.ConfigFactoryobject DeathClient {  def main(args: Array[String]) {    val system = ActorSystem("DeathWatchDemo",ConfigFactory.load("localsystem.conf"))    val parentActor = system.actorOf(Props(new ParentActor()), name="Parent")    parentActor ! "msg from childActor"    /**     * 给ParentActor和childActor点时间让她们初始化完成,不然的话下面的actorSelection会获取不到actor     */    Thread.sleep(500)    val childActor = system.actorSelection("/user/Parent/childActor")    childActor ! PoisonPill//    system.shutdown  }}import akka.actor.{Terminated, Props, Actor}class ParentActor extends Actor {  println("ParentActor construction method start ....")  val jason = context.actorOf(Props(new ChildActor()), name="childActor")  /**   * ParentActor 对ChildActor进行监控,可以监视到ChildActor的Death(收到Terminated 消息)   */  context.watch(jason)  println("ParentActor construction method end ....")  override def preStart() = {    /**     * 在新生成actor执行完类的构造方法后调用此方法     */    println("ParentActor preStart ...")  }  def receive = {    case Terminated(child) => println("ParentActor watch ChildActor:{} dead",child)    case msg : String => println("ParentActor received a message: " + msg)  }}import akka.actor.Actorclass ChildActor extends Actor {  def receive = {    case Some(msg) => println("ChildActor some msg is : " + msg)    case _ => println("ChildActor got a message")  }}




0 0
原创粉丝点击