Akka 概述
一、什么是 Akka?
Akka 基于 Actor 并发模型,提供了一个用于构建可扩展的(Scalable)、弹性的(Resilient)、快速响应的(Responsive) 应用程序的平台。
1.1. Actor 模型
Actor 模型被提出的初衷是解决并行处理的问题。在传统的面向对象模型下,完成一套复杂的逻辑功能,需要创建一些对象,每个对象包含一些方法,然后方法之间调来调去。在这个框架下,通常通过多线程来实现并行计算,涉及了线程阻塞的问题,以及资源冲突和锁的问题,代码的设计和编写变得复杂。
那 Actor 模型是怎么解决阻塞和锁的问题呢🤔️~
- Actor 模型把一套复杂功能拆分成不同的 actor,不同的 actor 完成不同的逻辑,actor 之间通过传递消息来进行交互。不同于方法的调用,actor 在发出消息后不需要等待返回,因此 actor 在发送消息后可以马上继续执行,避免了阻塞。
- 一个 actor 同时最多只能处理 1 条消息,并且消息是不可变的,也就不再需要锁了。
mapReduce 其实就可以理解为一种 actor 模型~
Actor 模型中并不是通过 Actor 对象的某个方法来告诉 Actor 需要做什么,而是给 Actor 发送一条消息。当一个 Actor 收到消息后,它有可能根据消息的内容做出某些行为,如更改自身状态,此时这个状态的更改是 Actor 自身进行的,并非由外界干预进行的。
1.1.1. 架构
在 Actor 模型中: 每个 actor 都有自己的地址, 在有对方 actor 地址后, actor 之间可以相互发送消息。 当 actor 正在处理消息时, 新来的消息按照发送时间顺序存储到 mailbox(邮箱)。mailbox 相当于一个小型的队列, 每个 actor 都
1.1.2.举个小栗子🌰~
需求:使用多线程找出 1000000 以内素数个数
共享内存
共享内存方式通过锁/同步的方式实现并发,每次同步获取当前值并让一个线程去判断值是否为素数,若是的话则通过同步方式对计数器加一
actor 模型
1.1.3. Actor 模型优势
Actor 模型已广泛应用在多种框架和语言中, 让用户可以聚焦到自己的业务逻辑上, 而不用像面向对象等编程模型那样需要关心死锁、竞争等问题。
- 非阻塞性
Actor 模型通过引入消息传递机制, 从而避免了阻塞。在 Actor 模型中, Actor 之间是异步通信的, 所以当一个 Actor 发送信息给另外一个 Actor 之后, 无需等待响应, 发送完信息之后可以在本地继续运行其他任务。 - 无需使用锁
Actor 从 MailBox 中一次只能读取一个消息, Actor 内部只能同时处理一个消息,是一个天然的互斥锁,所以无需额外对代码加锁 - 易扩展
每个 Actor 都可以创建多个 Actor, 从而减轻单个 Actor 的工作负载。当本地 Actor 处理不过来的时候,可以在远程节点上启动 Actor 然后转发消息过去。
二、Akka 架构设计
Akka 提供了创建 actor 系统的一些基础功能, 并且已经实现了控制基本行为必需的底层代码。
2.1. ActorSystem
Akka 通过 ActorSystem 来管理创建 Actor, 每个 JVM 实例内只有一个 ActorSystem。 当 ActorSystem 启动时,默认有3
个守护(guardian) Actor:
/: 根守护Actor,如同文件系统中的根,最先被创建,最后被销毁;
/system: 系统守护 Actor, Akka 本身以及基于 Akka 构建的某些模块会在该路径下创建子 Actor
/user: 用户守护 Actor, 在使用 Akka 过程中创建的 Actor 都会位于这个路径下。
当调用 ActorSystem.actorOf()方法时,会在
/user
下直接创建, 而当调用某 Actor 的 ActorContextactorOf() 方法时,会在该Actor下创建子 Actor。
2.2. Actor
Actor 是 Akka 中最核心的概念, 它是一个封装了状态和行为的对象,Actor 之间可以通过交换消息的方式进行通信,每个 Actor 都有
自己的收件箱 (Mailbox)
actor 角色的职责:
- actor 的输入是接收到的消息
- actor 接收到消息决定如何处理:如创建更多的actor,或发送更多的消息,或者确定如何去响应接到的下一个消息
- actor 处理完成任务后可以发送消息给其它Actor
2.3. ActorRef
Actor 的代理或者引用, 用户通过 ActorRef 来操作 Actor, 比如发送消息。
2.4. Dispatcher
Dispatcher 会将消息进行分发到对应的 MailBox, Actor 可以通过 receive() 方法来获取消息, 进行处理。
2.5. MailBox
当有消息到达 MailBox, 就会去调用 Actor 的receive() 方法, 将消息推送给 receive