一、什么是Akka?
Akka是一个异步非阻塞高并发处理框架,它是一系列框架,包括akka-actor, akka-remote, akka-cluster, akka-stream等,分别具有高并发处理模型——actor模型,远程通信,集群管理,流处理等功能。Akka具有一下特点:
Akka屏蔽了Java的多线程和锁,转而使用Actor模型,一般的工程师可以在不了解如何优化Java多线程编程的情况下,也能实现非常高性能的系统Actor设计之初就天然满足了分布式,而且粒度较小,单机上可以跑上百万的ActorAkka屏蔽了分布式集群中底层的通讯机制,对于开发者来说,只要根据业务写好Actor即可Akka直接提供了分布式下高可用、弹性、动态扩容的功能,无需再次开发。
二、Actor模型
由于AKka的核心是Actor,而Actor是按照Actor模型进行实现的,所以在使用Akka之前,有必要弄清楚什么是Actor模型。Actor模型最早是1973年Carl Hewitt、Peter Bishop和Richard Seiger的论文中出现的,受物理学中的广义相对论(general relativity)和量子力学(quantum mechanics)所启发,为解决并发计算的一个数学模型。
Actor模型所推崇的哲学是”一切皆是Actor“,这与面向对象编程的”一切皆是对象“类似。但不同的是,在模型中,Actor是一个运算实体,它遵循以下规则:
- 接受外部消息,不占用调用方(消息发送者)的CPU时间片
- 通过消息改变自身的状态
- 创建有限数量的新
Actor - 发送有限数量的消息给其他
Actor
很多语言都实现了Actor模型,而其中最出名的实现要属Erlang的。Akka的实现借鉴了不少Erlang的经验。
三、Actor模型的实现
Akka中Actor接受外部消息是靠Mailbox,参见下图

对于Akka,它又做了一些约束:
- 消息是不可变的
- Actor本身是无状态的
基本的Actor例子
引入依赖
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-actor_2.11</artifactId>
<version>2.4.7</version>
</dependency>
编写Actor
public class ActorDemo extends UntypedActor {
private LoggingAdapter log = Logging.getLogger(this.getContext().system(), this);
@Override
public void onReceive(Object message) throws Exception, Exception {
if (message instanceof String) {
log.info(message.toString());
System.out.println(getSelf() + "---->" + message + " " + Thread.currentThread().getName());
} else {
unhandled(message);
}
}
public static void main(String[] args) {
ActorSystem system = ActorSystem.create("sys");
ActorRef actorRef = system.actorOf(Props.create(ActorDemo.class), "actorDemo");
actorRef.tell("Hello Akka", ActorRef.noSender());
}
}
注意:ActorSystem是一个较重的存在,一般一个应用里,只需要一个ActorSystem。
在同一个ActorySystem中,Actor不能重名。
Actor的Path
Akka中的Actor不能直接被new出来,而是按一棵树来管理的,每个Actor都有一个树上的path:

实际上,在我们创建自己的Actor之前,Akka已经在系统中创建了三个名字中带有guardian的Actor:
/最顶层的root guardian。它是系统中所有Actor的父,系统停止时,它是最后一个停止的/userguardian。这是用户自行创建的所有Actor的父。这里的user跟用户没有一毛钱关系/system系统guardian
在上面的例子里,我们使用的是system.actorOf来创建Actor,actorOf返回的并不是Actor自身,而是一个ActorRef,它屏蔽了Actor的具体物理地址(可能是本jvm,也可以是其他jvm或另一台机器)。通过直接打印ActorRef看到Actor的path,比如本例是/app/user/echoActor。
像这种直接由system创建出来的Actor被称为顶层Actor,一般系统设计的时候,顶层Actor数量往往不会太多,大都由顶层Actor通过getContext().actorOf()派生出来其他的Actor。
Actor间的相互调用(tell, ask)
在Actor模型中,Actor本身的执行是不占用被调用方(akka中的话是消息的发送者)的CPU时间片,所以,akka的Actor在相互调用时均是异步的行为。
- tell 发送一个消息到目标
Actor后立刻返回 - ask 发送一个消息到目标
Actor,并返回一个Future对象,可以通过该对象获取结果。但前提是目标Actor会有Reply才行,如果没有Reply,则抛出超时异
Tell: Fire-forget
target.tell(message, getSelf());
其中第二个参数是发送者。之所以要带上这个是为了方便target处理完逻辑后,如果需要返回结果,可以也通过tell异步通知回去。
Ask: Send-And-Recieve-Future
Future<Object> future = Patterns.ask(echoActor, "echo me", 200);
future.onSuccess(new OnSuccess<Object>() {
@Override
public void onSuccess(Object result) throws Throwable {
System.out.println(result);
}
}, system.dispatcher());
Akka是一个异步非阻塞的高并发处理框架,基于Actor模型,提供分布式集群管理和流处理等功能。Actor通过消息传递改变状态,不占用调用方CPU时间,且Akka的Actor是无状态的。文章介绍了Akka的Actor模型概念,以及如何在Java中创建和使用Actor,包括tell和ask两种消息交互方式。
760

被折叠的 条评论
为什么被折叠?



