TIGERXC 2012-05-02
#与Akka集成
akka使用Actor模型,提高抽象层次,并提供一个更好的平台,建立正确的并发和可伸缩的应用程序。
对于容错,它采用“让崩溃模式,该模型已在电信业的巨大成功,主要用于建立自我修复 - 系统永不停止的应用程序。
Actor模型也为分布式传输和真正可扩展、可容错应用的基础提供了抽象。
1.应用程序Actor系统
akka2.0能够在若干个被称作Actor系统的容器上工作。Actor系统管理为了运行它包含的Actors的配置资源。
一个Play应用定义了一个特殊的actor系统,用来让应用使用。这个actor系统跟随应用的生命周期,当应用程序重启时,它会自动重启。
Play并不反对你在Play应用中使用另外的actor系统。Play默认的actor系统仅仅是一个启动几个actor的便捷方式,而不需要设置你自己的actor系统。
同play.libs.Akka助手可以访问默认的应用程序actor系统:
ActorRef myActor = Akka.system().actorOf(new Props(MyActor.class));
2.配置
默认的actor系统的配置从Play的配置文件中读取。例如,在conf/application.con中加入如下几行,可以配置应用程序actor系统的默认Dispatcher(转发器)。
akka.default-dispatcher.core-pool-size-max = 64 akka.debug.receive = on
3.将Akka的Future转换为Play的Promise
当你与Akka进行异步交互的时候,我们会得到Future对象,你可以使用play.libs.Akka.asPromise()提供的转换方法轻易地将它转换为Play的Promise。
import static akka.pattern.Patterns.ask; import play.libs.Akka; import play.mvc.Result; import static play.mvc.Results.async; import play.libs.F.Function; public static Result index() { return async( Akka.asPromise(ask(myActor,"hello", 1000)).map( new Function<Object,Result>() { public Result apply(Object response) { return ok(response.toString()); } } ) ); }
3.异步执行代码块
Akka的一个普通用例是当有一些并发执行的计算时,不需要actor的额外工具。
如果你发现你创建以一个Actor池的理由是为了进行并行计算,那么这里有更加简单快速的方式:
import static play.libs.Akka.future; import play.libs.F.*; import java.util.concurrent.Callable; public static Result index() { return async( future(new Callable<Integer>() { public Integer call() { return longComputation(); } }).map(new Function<Integer,Result>() { public Result apply(Integer i) { return ok("Got " + i); } }) ); }
4.一部任务调度
你可以调度发送消息给actors,并且执行任务(函数或者Runnable实例)。你会得到一个可撤销的返回,你可以调用撤销的回调来取消调度操作的执行。
举个例子,没30秒向testActor发送一个消息:
Akka.system().scheduler().schedule( Duration.create(0, TimeUnit.MILLISECONDS), Duration.create(30, TimeUnit.MINUTES) testActor, "tick" )
另一个例子,从现在起10秒后执行一个代码块:
Akka.system().scheduler().scheduleOnce( Duration.create(10, TimeUnit.SECONDS), new Runnable() { public void run() { file.delete() } } );