概述
近年来随着Spark的火热,Spark本身使用的开发语言Scala、用到的分布式内存文件系统Tachyon(现已更名为Alluxio)以及基于Actor并发编程模型的Akka都引起了大家的注意。了解过Akka或者Actor的人应该知道,这的确是一个很不错的框架,按照Akka官网的描述——使用Akka使得构建强有力的并发与分布式应用将更加容易。由于历史原因,很多Web系统在开发分布式服务时首先会选择RMI(Remote Method Invoke ,远程方法调用)、RPC(Remote Procedure Call Protocol,远程过程调用)或者使用JMS(Java Messaging Service,Java消息服务)。
但是使用RMI只能使用java语言,而且开发、执行效率都不高;RPC框架虽然可以通过匹配方法签名的方式比RMI更灵活,但是其存在调用超时、调用丢失等缺点;JMS方式虽然可以通过At Least Delivery Once、消息持久化等机制保证消息不会丢失,但是只能作为一种跨服务的生产者、消费者编程模型使用。Akka不但处理了以上问题,而且还可以使用Actor作为并发编程模型,减少java多线程编程的阻塞、调度、上下文开销甚至死锁等问题。此外,Akka还提供了集群Sharding、流处理等功能的支持,更易于实现有限状态自动机等功能。所以有心的开发者势必会关心如何在最常见的Java系统中使用它,如何与Spring集成?
本文参考Akka官方使用文档,根据自身的经验和理解,提供Akka与Spring集成的方案。本文不说明Spring框架的具体使用,并从Spring已经配置完备的情况开始叙述。
Actor系统——ActorSystem
什么是ActorSystem?根据Akka官网的描述——ActorSystem是一个重量级的结构体,可以用于分配1到N个线程,所以每个应用都需要创建一个ActorSystem。通常而言,使用以下代码来创建ActorSystem。
ActorSystem system = ActorSystem.create("Hello");
不过对于接入Spring而言,通过IOC(Inversion of Control,控制反转)的方式会更接地气,你可以这样:
<!-- AKKA System Setup -->
<bean id="actorSystem" class="akka.actor.ActorSystem" factory-method="create" destroy-method="shutdown" scope="singleton">
<constructor-arg value="helloAkkaSystem"/>
</bean>
然后在你需要的地方依赖注入即可。
Actor编程模型
有关Actor编程模型的具体介绍可以看我的另一篇博文——《Spark如何使用Akka实现进程、节点通信的简明介绍》,里面有更多的介绍。需要补充的是,在最新的Scala官方网站上已经决定废弃Scala自身的Actor编程模型,转而全面拥抱Akka提供的Actor编程模型。
我们可以通过以下代码(代码片段借用了Akka官网的例子)创建一个简单的Actor例子。
Greeter是代表问候者的Actor:
public class Greeter extends UntypedActor {
publ