简单学习一下 Akka 这个高并发、分布式的第三方 libtool/runtime 。
前言
好玩的文章先 mark
- JVM 并发框架 Akka(系列,十讲)
- akka 介绍
- Akka 学习笔记(经典 student-teacher 模型,挺生动的,推荐初学者)
- Actor 模型
- Akka 源码分析-ActorSystem
再贴一段 wikipedia 上的介绍,英文版,中文版(非常不全,基本没翻译)
Akka 是一套开源工具和运行时,便于构建 JVM 上的并发应用和分布式应用。Akka 支持多种并发编程模型,不过,由于受到 Erlang 启发,Akka 尤其强调基于演员的并发模型。
(上面中文 wiki 翻译 Actor 我觉得用“参与者”更准确)
Akka is a free and open-source toolkit and runtime simplifying the construction of concurrent and distributed applications on the JVM. Akka supports multiple programming models for concurrency, but it emphasizes actor-based concurrency, with inspiration drawn from Erlang.
Actor 模型
Actor 模型解决了多线程编程中出现的资源冲突/堵塞,适用于对一致性需求不是很高、对性能要求较高的场景,出现于 1973 年,在 Erlang 语言中得到广泛支持和应用。
一致性:指 CAP 三原则中的数据一致。
在面向对象编程中,万物皆对象。类似的,在 Akka 的世界里,万物皆 Actor,参与者。
关键词/关键类:
- ActorSystem
- ActorRef
- Actor
ActorSystem 是一切的起点,定义了 system name,可以传入多线程的 ExecutionContext。
1 | val actorSystem: ActorSystem = ActorSystem("name") |
ActorRef 一般通过actorOf
来创建,可以传入一些配置项.
1 | val actorRef: ActorRef = actorSystem.actorOf(...) |
Actor 是一个 trait 类型(scala 概念,暂时理解为类似 Java 的 interface/抽象类),需要 override 里面的 receive 方法来给定 Actor 收到消息后的行为。
1 | override def receive: Receive ={...} |
Actor 模型实现的场景:
- 应用 A 和应用 B 不能/不允许直接通信,他们要通过一个邮箱/message queue 来相互对话。
- message 一旦发出则不能修改。
- 各自的收件箱按照 FIFO 处理收到的 message。
- 可以选择收到了这封信但不处理/不给出答复。
组成 Actor 的三部分:
- state 状态,private,外部无法访问、无法修改
- behavior 行为
- mailbox 邮箱
Actor 从邮箱中取出一条消息时,可以(不按顺序地)进行下面三件事:
- create new Actors
- send message to other actors
- 指定下一条消息到来时的behavior
Actor 的两种任务调度方式:
- 基于线程
- 基于事件
TODO ↑ 这部分代码在哪里实现?以及如何调用?
Actor 缺点
一个 ActorSystem 可能有上【百万】个 Actor。当所有逻辑都运行在 Actor 中时,Actor 粒度很难控制,很有可能造成 Actor 数量爆炸。
TODO ↑ 那这时候会发生什么?
Akka Way of Working
Scala 中好玩的异步调用方法,其中之一就是借用 Akka 框架来起多线程了。上面说的都是 Actor 模型,那么 Akka 为了实现这套模型,又做了什么?又添加了什么 feature?
Akka 主要是一个异步的消息处理机制,核心就是 Actor 模型,actor 之间通过内部“邮箱”实现进行 FIFO 的消息处理。Akka 的主要组成部分如下:
- akka-actors
- akka-stream
- akka-http
- akka-cluster
- akka-sharding
- distributed data
- akka persistence
- akka management
- alpakka