高并发异步框架Akka使用(二)、Actor模型

提到Akka就不能不提Actor模型,他是Akka绕不过的话题,也是Akka的核心所在。
那么究竟什么是Actor模型呢?
我们可以先建立这样一个概念,一个Actor就对应于Java中的一个Java Bean,是一个边界实体。但是他不完全等同于Java Bean,或者说这是一个错误的等价。之所以这么说,就是想给大家有个经验上的概念。
一个Actor从内部看,可以做很多事,但从外部来看,他的职能又是单一的。这一概念可能 不太好理解,我们暂且放下,后面会慢慢介绍。
Actor和Actor之间不能直接调用或交互,他们通过邮件来交互,每个Actor都有一个自己的信箱,里面存放着其他Actor发来的邮件。同时每个Actor也可以给别人发邮件。
参见下面这张图,有四个actor,actor之间通过mail交互通信,他们共同组成了一个完整的系统,就是Actor System。

Actor可以处理不同类型的邮件,每一个类型的邮件有一个专门的处理方法。
好了,我们现在来做一个通俗的类比,让大家有一个更直观的理解。
Actor System就好比我们这个世界,我们每一个人就是一个Actor,我们每个人有不同的技能,有的人会织衣,有的人会捕鱼,有的人会打猎。
现在有这样一个需求,有一个人A,需要一批貂皮大衣和鱼皮马甲,他自己啥也不会,怎么办呢?他决定找其他人帮忙:

    1.A给猎人发了一封信,让猎人帮他打一只貂,
    2.猎人打好了貂,通过顺丰发给了他,于是A有了貂皮;
    3.A给渔夫发了一封信,让农夫帮他打一条鱼,
    4.渔夫打好了鱼,通过圆通发给了他,于是A有了鱼皮;
    4.A又给织衣人发一封信,同时把貂皮、鱼皮通过顺丰寄给了他,让织衣人帮他做貂皮大衣和鱼皮马甲。
    5.织衣人做好了貂皮大衣和鱼皮马甲用顺丰发给了他,最终他拥有了貂皮大衣和鱼皮马甲。

每个人都有自己的特殊技能,比别人做的又快又好。这样就构成了一个完整的世界,一个人人有衣穿,人人有田种的世界。每个人各司其职,其乐融融。
以上就是actor和actor system的简单类比。
可是大家会有这样的疑问:为什么A自己不打猎、捕鱼、织衣,交给这么多人做,不是更麻烦吗?万一其中一件快递丢了呢?那不是满盘皆输。
仔细想一想,确实是这样的,生活中掌握多项技能的人大有人在。但是当你回头想想,你会发现这样的模型存在问题:

    如果只交给一个人,他去世了怎么办?
    现在又有人提出要做貂皮马甲怎么办?
    如果很多人需要大衣和马甲,都来找他,他做不完怎么办?
    同样存在的问题,他们也会存在快递丢失;

回到我们的软件系统中,大家不难发现,这不就是一个传统的All in one的系统吗?所有的功能都整合在这个大系统中;一旦需求有变动,需要修改很多代码;请求一大,负载狂飙;因为一些其他问题,大致请求失败,业务被迫中断。
因此我们需要一个解决的办法,这也就是微服务产生的根源。这时候,你可能会发现,Akka还真有点像那么回事。

    akka中有不同的actor,处理不同的任务
    通过actor模型拆分后,我们可以构建异构的系统
    对于来往的邮件,Akka支持持久化,我们可以做持久化,在出错时可以重做。
    Akka还支持集群,同一类型任务可以交给集群处理,避免单点故障。

通过这样的改进,我们可以做很多事情。譬如现在织衣人有钱了,他自己不用亲自织衣服了,他买了机器,通过织衣服的机器来做。对于整个系统来说,变化不大,大家还是给他发邮件,寄材料。对于别人来说,他的变化是无感知的。同样的,越来越多的人加入织衣行列,大家也不必关心,只管发邮件,寄材料,所有的这些由织衣人自己来解决。这样就不会出现一个织衣人病了,大家就不能收到衣服的情况。
这时候还有可能有另外一种情况,现在是冬天,大雪纷飞,那么织衣人就要先织造貂皮大衣,鱼皮马甲可能要暂停,待到冬去春来再去织马甲,或者根本就不去织马甲。
传统的系统,遇到流量高峰,想要去实现这样的需求还是很难的,首先剥离织貂皮大衣和马甲就是一件很麻烦的事,或者说根本没办法实现,更不要说后面再去重新织马甲。
而Akka框架却很容易做到,只要新增加一个Actors就好了,将原先织马甲的逻辑剪切到新的Actor中,新的Actor就拥有了这项技能,当流量高峰来临时,我们保证主要、核心业务正常,其他的暂时关停,持久化相关数据,等到系统正常时候再补做。总体来说还是很方便的。
Akka的有点远不止此,当然这些都是和微服务息息相关的,结合起来还是很好理解的。
在Akka框架中actor是其中最小的执行粒度,是Akka中的基础模型。类似于Java中的线程,但是他比线程轻量很多,更像是golang中的协程的概念。

发表评论

邮箱地址不会被公开。 必填项已用*标注