初识Akka

万事皆有因

说是初识吧,也不算,因为很久以前因为听Scala的介绍的时候,有人就提到过Akka这个库。但是个人并没有深入了解该库,近期工作需要就将Akka这个库下载下来看了下。因为自己是个准Erlang程序员,对Actor模型还算是比较了解,就写下这个Blog来记录下,我对Akka的初步认知。


Actor模型

Actor模型可以说是并发编程中非常常见的一种模型,该模型是Carl Hewitt1973年提出的

那么Actor模型是怎么工作的呢?

  1. Actor是独立的,每个Actor只管理自己的内部数据,对外暴露一个通信用的邮箱

  2. Actor都是通过向另一Actor暴露的邮箱发送消息来进行通信

  3. Actor之间的通讯行为是异步的

那么Actor模型中的Actor可以做什么呢?

  1. 接收消息并进行相应处理

  2. 创建新的Actor

  3. 发送消息给另一个Actor


Erlang和Akka的差异

Akka和Erlang都实现了Actor的模型,不过它们在实现这个模型的时候还是有很大差异的。我就初步介绍下这些差异:

  1. Erlang是用整个语言来实现了Actor模型,而Akka只是个JVM上的库(完全是废话,但是这是根本性的问题,其中也体现了专用虚拟机和通用虚拟机的差异)。

  2. Erlang的Actor表现为Erlang的进程(直被Erts内部的POSIX线程调度),Akka的Actor就是一个类(使用Java的线程调度)。当Erlang中的Actor(Erlang进程)死亡的时候,会被直接清理掉,而Akka的Actor死亡后需要等到JVM的GC触发了才会进行彻底性的清理。

  3. Erlang的调度方式是抢占式公平调度(专用虚拟机TT,软实时的特性),而Akka的调度是协作式调度(完全依赖Actor主动放弃调度器,Go中的goroutine也是这个道理,但是两者之间应该存在差别,目前无法确定,等深入的读Akka的代码时,再补充吧)。


关于调度

为什么将调度特别提一下呢?因为很多Erlanger长时间使用Erlang,容易有先入为主的倾向,很容易写出影响Akka调度的代码(我已经干过一次了TT)。

Erlang的调度是公平调度,且是抢占式的,所以我们可以写的代码(不使用nif或Driver的前提下)不会影响调度器,只会影响我们自己业务逻辑。

举个例子:

我们的CPU为2Core时,process数为200,每个process平均获得CPU的能力 1/200 2   1% 。

我们的CPU为4Core时,process数为200,每个process平均获得CPU的能力 1/200  4  2% 。

我们的CPU为8Core时,process数为1000,每个process平均获得CPU的能力 1/1000 * 8 Core = 0.8%。

也就是说,Erlang在进程数不变的时候,增加CPU会增加每个Erlang进程的执行时间。


好了Akka的调度是协作式的调度,这就代表着我们无法得到上面例子中的算式。当一个调度器上的某个Actor在做一个非常长时间的计算,完全由可能让调度器上的其它Actor不能按时调度(不能保证软实时性)。所以不能在Akka的Actor中执行例如同步的IO操作等。




你可能感兴趣的:(erlang,akka,actor,调度,CPU能力)