初识 Akka
虽然Akka基于Scala而非Java语言编写而成,但由于Scala最终还是被编译为Java字节码并运行在JVM之上,所以我们可以认为Akka属于Java领域。
Akka官方对Akka的介绍如下。
●是对并发、并行程序的简单的高级别的抽象。
●是异步、 非阻塞、高性能的事件驱动编程模型。
●是非常 轻量的事件驱动处理机制(1GB内存可容纳约270万个Actor)。
通过以前文章对μJavaActors的讲解,我们知道,一 一个实际的Actor 系统是由许多个Actor实例组成的-一个复杂的树状结构,父Actor负责子Actor的生命周期并对它们实施必要的监管与控制,Akka项目则更加清晰地描述和定义了与之相关的编程模型。如下所示给出了Akka中的Actor层级与监管的示意图。
从上图中还可以看到,Akka中的每个Actor都有一个Path (路径),对于一个Actor子系统ActorSystem (类似于μJavaActors中的- -个ActorManager,维护-一个Actor 命名空间)来说,顶级根路径是“/”,下面有两个子路径, 分别是user (用户空间)路径与system (系统空间)路径,在前者的路径分支上挂接了我们自己开发的Actor,后者则是Akka本身的系统级的Actor所在的路径。
如下所示是一个典型的Akka Actor 的Path层级的结构示意图,我们看到每个下一层级的Actor的Path全路径的名称都是从根节点出发的完整路径,类似于文件目录结构的设计思路。
而将user空间与system空间分离的做法,又借鉴了Linux内核的思想,将系统级的Actor识别出来,从而针对性地实现了精细化调度及增强系统内核的稳定性与容器能力。
在Akka的Actor Path设计里还融入了URL的思想,使得Akka天然具备了分布式计算的能力。下面是Actor Path的完整定义方式:
akka://<actorsystemname>@ <hostname>: <port>/<actor path>
如果我们要访问位于一个远程机器10.0.0.1. 上的某个Actor,则可以这样引用:
ActorRef actor = context.actorFor ("akka:/ /app@10.0.0.1:2552/user/actorxxxx") ;
在分布式系统中,在通常情况下我们会部署多个Actor实例来响应某个业务请求,Akka 为此提供了基于Router组件派发请求的解决思路。如下所示是一个使用Router的原理图。
首先,我们定义一个Router (其实也是-一个Actor),然后为这个Router设置后端的转发路
由(routee), 客户端在发送消息时,要先获取Router的Path,并将消息发到Router上,最后由
Router将消息转发到后端的某个具体Actor.上。如下所示是来自Akka官网的一段Router配置
代码:
akka. actor . deployment {
/parent/ remoteGroup {
router = round- robin-group
routees .paths = [
"akka. tcp:/ /app@10.0.0.1:2552/user/workers/w1",
"akka. tcp:/ /app@10.0.0.2:2552/user/workers/w1",
"akka. tcp:/ /app@10.0.0.3:2552/user/workers/w1"