Akka的设计理念

Akka有两种模式
1) 以库的模式:在web应用中,放到Web-INF/lib中或作为一个普通的Jar包放进classpath
2) 以微内核形式:提供一个捆绑的机制,可以通过微内核启动一个应用,首先创建一个Bootable类,startup,shutdown管理应用的启动和关闭。
Let It Crash模型
透明的分布式系统,
真正的可扩展高容错应用的基础进行抽象
Akka特点:
1)系统中的所有事物都可以扮演一个Actor
2)Actor之间完全独立
3)在收到消息时,Actor所采用的所有动作都是并行的,在一个方法中的动作没有明确的顺序。
4)Actor有标识和当前行为描述。
5)Actor可能被分解为原始的和非原始的。
6)非原始Actor有由一个邮箱地址标识的标识。
7)当前行为有一组知识和定义Actor在收到消息时采取的动作组成。
8)消息传递是非闭塞和异步的,其机制是邮件机制。
9)所有的消息发送都是秉性的。
1、Akka框架模型
1)对并发/并行程序的简单、高级别的抽象
2)异步、非堵高性能的事件驱动编程模型
3)非常轻量的事件驱动处理,
Akka框架中每个Actor都有一个通信地址,唯一的URL,
akka.tcp://[email protected]:2551/ user /simple
akka.tcp协议
backend AkkaSystem的名称
127.0.0.1 服务IP地址
2551 端口
user 默认监管
simple 顶级Actor

2、创建Actor

import akka.actors.{Actor,Props,ActorSystem}
object Test{
def main(args:Array[String]){
val _system=ActorSystem(“HelloAkka”)
val test=_system.actorOf(Props[Test],name=”test”)//缺省方法创建Actor,返回一个实例的引用
test!”just to do it!”
_system.shutdown()

}
}
class Test extends Actor{
override def receive:Receive={
case str:String=>println(str)
case_=>//处理未知消息
}
}
//使用Actor的context创建Actor
import akka.actors.{Actor,Props,ActorSystem}
class Test2 extends Actor{
override def receive:REceive={
case str:String=>println(“receive msg”+str)
case_=>
}
}
class FirstActor extends Actor{
val testActor =context.actorOf(Props[Test],”test”)
println(“test Actor’s monitor:”+testActor.path.parent.getElements.toString)
override def prestart()={
println(“FristActor’s preActor Method was called!”)
}
override def receive:Receive={
case msg=>testActor!msg//若加上匿名Actor
//case str:String=>
//context.actorOf(Props(new Actor{
//def receive:Receive={
//case msg:String=>
//println(msg)
//context.stop(self)
//}
//})).forward(str)
case_=>
}
}
object Test2{
def main(args:Array[String]){
val _system=ActorSystem(“HelloAkka!”)
val first=_system.actof(Props[FirstActor],name=”firstActor”)//缺省
//非缺省   _system.actof(Props(new FirstActor(“Regan”)),name=”firstActor”)
first!”just to do it!”
println(“firstActor ‘s monitor:”+ first.path.parent.getElements.toString)
}
}

3、Actor API
Actor trait 中的成员:
成员变量self:本·Actor的ActorRef
成员变量sender:最近收到的信息的发送方Actor
成员方法supervisorStrategy:用户可通过此重写对子Actor的监管策略
隐式成员变量context:暴露当前Actor和当前消息的上下文信息
如:
用于创建子Actor的actorOf方法
Actor所属的系统
父监管者
所监管的子Actor
生命周期监控
hotswap行为栈

其余生命周期函数:

def prestart(){}//启动Actor之前调用
def preRestart(reason:Thowable,message:OPtion[Any]){//在重启之前调用
context.children foreach(context.stop(_))//递归停止子Actor
postStop()//调用postStop方法释放资源
}

def postRestart(reason:Throwable){preStart()}//再重启之后调用preStart()做启动准备
def postStop(){}//在Actor停止之后,清理释放暂用资源。

使用DeathWatch进行生命周期监控
简书中的介绍:
作者:JasonDing
链接:http://www.jianshu.com/p/16de393ec5b4
來源:简书

在Akka中生命周期监控通常指的是DeathWatch。
除了父actor和子actor的关系的监控关系,每个actor可能还监视着其它任意的actor。因为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时,监管者也将会受到影响。
说明
为了在其它actor结束时(i.e.永久终止,而不是临时的失败和重启)收到通知,actor可以将自己注册为其它actor在终止时所发布的 Terminated消息的接收者。这个服务是由actor系统的DeathWatch组件提供的。
DeathWatch是进行Actor的生命周期监管,使用watch方法对child进行监控,并在Actor终止后,收到Child Actor发出的Terminated消息。

import akka.actor._
object Test3{
def main(args : Array[String])
{
val _system=ActorSystem(“HelloActor”)
val watchActor=_system.actorOf(Props[WatchActor],name=”WatchActor”)
watchActor!”kill”
}
}
class WatchActor extends Actor{
val child=context.system.deadLetters
println(lastSender)
def receive:Receive={
case “kill”=>context.stop(child)
println(“child stop”)
lastSender=sender
case Terminated(‘child’)=>
println(“receive child Terminated message”)
lastSender!”finished”
}
}

Hook函数的调用

启动Actor后他的preStart方法立即执行,
override def prestart(){
//注册其他Actor
//为启动Actor做准备
someService!Register(self)
}

Actor重启:
def Restart(reason:Throwable,message:Option[Any]){
context.children foreach(context.stop(_))//递归停止子Actor
postStop()//调用postStop方法释放资源
//调用actorOf方法创建新的实例
//新的Actor的postRestart方法被调用,携带着导致重启的异常信息,
//对消息的处理将在postRestart回调函数返回后继续,触发异常的信息不会被接受,消息照//常放在邮箱队列中。

}
终止Hook:
Actor终止后,postStop回调函数用来取消该Actor在其他服务中的注册,在Actor的消息队列被禁止后进行,之后发给Actor的消息被重定向到ActorSystem的deadLetters中

查找Actor
每个Actor拥有一个唯一的逻辑路径,从Actor系统的根开始的父子链构成,
也拥有一个物理路径,
context.actoerFor(“/user/serviceA/aggregator”)//查找绝对路径
context.actorFor(“../joe”)//查找同一父监管下的兄弟。
路径被解释成java.net.URL, “/”开头为绝对路径,从根监管者(“/user”的父亲)开始查找,否则会从当前Actor开始。
“..”开始,找到当前所遍历到的Actor的上一级,否则向下一级寻找具有该名字的子Actor,
远程Actor
context.acterFor(“akka://qpp@otherhost:9999/user/ service”)

消息的不可变性
推荐使用Scala case class,和String,Int,Boolean等原始类型,其他类型scala.Tuple2, scala.List, scala.Map
发送消息
1)!意思是“fire-and-forget”,异步发送一个信息并立即返回,也称为tell
2)?异步发送一个信息并返回一个Future代表一个可能的回应,ask

转发信息
oneActor.forward(message),将信息转发给oneActor
接收信息
Actor必须实现receive方法来接受信息,
回应信息
sender表示消息的发送方,可以使用sender!replyMsg给消息发送方回应信息。
如果没有sender,那就默认为“死信”Actor的引用。

case request=>
val result=process(request)
sender!result//默认为死信actor

超时机制,必须设置receiveTimeout属性,并声明一个处理ReceiveTimeout对象的匹配分支,

import akka.actor.ReceiveTimeout
import akka,util,duration,_
class MyActor extends Actor{
context.setReceiveTimeout(30 milliseconds)//context设置超时信息。
def receive={
case “Hello”=>println(“Hello”)
case ReceiveTimeout=>throw RuntimeException(“receive timeout”)
}

}

终止Actor
调用ActorRefFactory或ActorContext或ActorSystem中的stop方法来终止一个Actor
通常用context来终止子Actor,用system来终止顶级Actor
还可以向Actor发送akka.actor.PoisiomPill消息,这个消息处理完成后Actor会被终止。
become/Unbecome
akka使用消息处理HotSwap,通过become和Unbecome在运行时动态替换消息处理的代码,become需要一个PartialFunctiom[Any,Unit]参数作为新的消息处理实现,被替换的代码被存在一个栈中,可以通过push和pop替换。

import akka.actor.{Props,actorSystem,Actor}
import akka.event.Logging
case object HotSwap
class HotSwapper extends Actor{
import context._
val log=Logging(system,this)
def receive ={
case HotSwap=>
log.info(“Hi”)
become{
case HotSwap=>
log.info(“Ho”)
unbecome()
}
}
}
object HotSwapper extends App{
val _system=ActorSystem(“HotSwapSystem”)
val swap=system.actorOf(Props[HotSwapper],name=”HotSwapper”)
swap!HotSwap//打印Hi

swap!HotSwap//打印Ho

swap!HotSwap//打印Hi

swap!HotSwap//打印Ho

}

杀死Actor

发送Kill消息杀死Actor,也可以通过stop方法,PoisionPill消息来完成。
Kill使Actor抛出ActorKilledExeception异常。

有类型的Actor
http://blog.csdn.net/laiwenqiang/article/details/43935187

终止有类型Actor
TypedActor(system).stop(mySquarer)
TypedActor(system).poisonPill(otherSquarer):异步终止与指定代理关联的有关联Actor

你可能感兴趣的:(scala)