akka 学习笔记

来源:互联网 发布:淘宝win10专业版激活码 编辑:程序博客网 时间:2024/05/16 18:10

博客地址: http://blog.csdn.net/yueqian_zhu/


一、actor启动

Actor 在创建后将自动异步地启动。当你创建 Actor 时它会自动调用 Actor trait 的preStart 回调方法。这是一个非常好的用来添加actor初始化代码的位置

actorOf的第一个参数是一个Props对象:

val myActor = context.actorOf(Props[MyActor], name = "myactor")val myActor = system.actorOf(Props(new MyActor("...")), name = “myactor”)也可以通过Props().withXXX()来设置。如Props().withCreator(new MyActor).withDispatcher(“my-dispatcher")
二、actor receive中的模式匹配

如果希望处理未知的消息,需要提供一个缺省的case分支。否则会有一个 akka.actor.UnhandledMessage(message, sender, recipient) 被发布到 ActorSystem的 事件流(EventStream)中

三、在actor的receive中创建actor

需要避免调用外层actor的方法,这会破坏actor的封装,可能会引入同步bug和资源竞争,因为其它的actor可能会与外层actor同时进行调度。

四、生命周期监控

使用DeathWatch进行生命周期监控:为了在其它actor结束时 收到通知, actor可以将自己注册为其它actor在终止时所发布的 Terminated 消息 的接收者. 这个服务是由actor系统的 DeathWatch 组件提供的。

val child = context.actorOf(Props.empty, "child")context.watch(child) // <-- 这是注册所需要的唯一调用
之后,child结束后,能收到Terminated 消息.

多次注册并不表示会有多个消息产生,也不保证有且只有一个这样的消息被接收到

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

五、ask/?

用来异步发送一个消息,并返回一个Future。ask调用需要implicit val timeout = Timeout(5 seconds)来指定超时时间。其实ask 操作包括创建一个内部actor来处理回应,必须为这个内部actor指定一个超时期限,过了超时期限内部actor将被销毁以防止内存泄露。

常用 pipeTo 在future上安装一个 onComplete-处理器来完成将收集到的 Result 发送到其它actor的动作。如:

val f: Future[Result] = …f pipeTo actorA或者pipe(f) to actorA
如果ask的接收方处理异常时需要发送一个 Failure 消息给发送方以填充Future。如:

try {  val result = operation()  sender ! result} catch {  case e: Exception ⇒    sender ! akka.actor.Status.Failure(e)    throw e}
如果一个actor没有完成future, 它会在超时时限到来时过期,以 AskTimeoutException来结束。此时需要onComplete之类的回调方法来处理ask调用触发的异常AskTimeoutException,否则在异常发生时,actor实例将被丢弃而生成一个新的实例

六、转发消息

你可以将消息从一个actor转发给另一个。虽然经过了一个’中转’,但最初的发送者地址/引用将保持不变。

otherActor.forward(message)
七、热替换 become/unbecome

become接收一个PartialFunction[Any,Unit]类型参数作为新的消息处理实现,称为热替换。可以理解为一个栈,become后往栈顶push一个新的处理,unbecome后将栈顶的pop出来,又恢复之前的处理方式。

八、异常处理

消息在处理过程中抛出异常,这个消息将被丢失,不会被放回到邮箱中。所以如果你希望重试对消息的处理,你需要自己抓住异常然后在异常处理流程中重试. 请确保你限制重试的次数,因为你不会希望系统产生活锁 。邮箱没有任何变化。如果actor被重启,邮箱会被保留。邮箱中的所有消息不会丢失。如果抛出了异常,actor实例将被丢弃而生成一个新的实例。

九、扩展消息处理链

orElse
十、定时器

ActorSystem中有scheduler/scheduleOnce方法,返回一个Cancellable对象。可以通过cancel方法取消定时器。

十一、Await

通过Await.result和Await.ready来阻塞获取future的结果,由于通过ask返回的类型为Future[Any],所以一般Await.result(future, timeout.duration).asInstanceOf[String]来进行类型转换。在使用非阻塞方式时,最好使用mapTo将Future转换到期望的类型。如果转换成功, mapTo 方法会返回一个包含结果的新的 Future, 如果不成功,则返回 ClassCastException 

十二、监管机制

在actor中通过override val supervisorStrategy来定义一个监管机制。

缺省监管机制:

如果定义的监管机制没有覆盖抛出的异常,将使用上溯 机制.

如果某个actor没有定义监管机制,下列异常将被缺省地处理:

ActorInitializationException 将终止出错的子 actor

ActorKilledException 将终止出错的子 actor

Exception 将重启出错的子 actor

其它的 Throwable 将被上溯传给父actor

如果异常一直被上溯到根监管者,在那儿也会用上述缺省方式进行处理。

十三、Agent

Agent 提供对独立的内存位置的异步修改.对所有agent的更新操作在一个线程池的不同线程中并发执行。在每一个时刻,每一个Agent最多只有一个 send 被执行. 从某个线程派发到agent上的操作的执行次序与其发送的次序一致,但有可能与从其它(线程)源派发来的操作交织在一起。

十四、测试

TestKit

0 0