谈到Akka就必须介绍Actor并发模型,而谈到Actor就必须看一篇叫做《A Universal Modular Actor Formalism for Artificial Intelligence 》的论文,它最早发表于1973年,提出了一种并发计算的理论模型,Actor就源于该模型。

  在Actor模型中,actor是一个并发原语,简单的说,一个actor就是一个工人,与进程或线程一样都能够工作或处理任务。其实这还有点不好理解,我们可以把它想象成面向对象编程语言中的一个对象实例。在OOP中一个对象可以访问或修改另一个对象的属性,也可以直接调用另一个对象的方法。例如下图,person1给person2发送了一个消息,直接调用方法就行了。深入底层执行逻辑的话,结果就是JVM转到sayHello的代码区,一步步执行。

public class HelloWorld {
private String name = "";
public HelloWorld(String name){
this.name = name;
}
public String getName(){
return this.name;
}
public void sayHello(HelloWorld to, String msg){
System.out.println(to.getName()+" 收到 "+name+" 的消息:"+ msg);
}
} public class OOPInvoke {
public static void main( String[] args ) {
HelloWorld person1 = new HelloWorld("Person1");
HelloWorld person2 = new HelloWorld("Person2");
person1.sayHello(person2,"Hello world");
}
}

  sayHello在一个线程中执行基本没有问题,但是多个线程执行时,就可能出问题了,因为在执行sayHello的时候person2的name值可能被其他线程修改。这是一个name字段,意外修改没有关系,但如果是一个金额字段呢?

  actor和对象的不同之处在于,actor的状态不能直接读取、修改,actor的方法不能直接调用。actor只能通过消息传递的方式与外界通信。每个对象都有一个this指针,代表对象的地址,可以通过该地址调用方法或存取状态;与此类似,actor也有一个代表本身的地址,但只能向该地址发送消息。

  简单点说,actor通过消息传递的方式与外界通信。消息传递是异步的。每个actor都有一个邮箱,该邮箱接收并缓存其他actor发过来的消息,actor一次只能同步处理一个消息,处理消息过程中,除了可以接收消息,不能做任何其他操作。前面这段话,我加粗、倾斜、加下划线、还用红色字体标出,你就应该知道有多重要了,这就是actor模型的本质。

  Actor模型的另一个好处就是可以消除共享状态,因为它每次只能处理一条消息,所以actor内部可以安全的处理状态,而不用考虑锁机制。标红的这两句话如果可以理解透彻,基本上Actor模型的精髓你就掌握了。

  那么读者可能会问,每次只处理一个消息,这不是会严重的影响性能么?废话,一次处理一个消息当然影响性能了。不过,如果你恰当的运用Akka和Actor模型,完全可以不必关心性能的问题。下面是Actor模型的几个基本原则:
       (1)所有的计算都是在actor中执行的
       (2)actor之间只能通过消息进行通信交流
       (3)为了响应消息,actor可以进行下列操作
               a.  更改状态或行为
               b. 发消息给其他actor
               c. 创建有限数量的子actor

  看了上面几个基本原则,你是不是更加鉴定的认为Actor模型没啥用?嗯,这就对了,因为我当初也是这么认为的。一次处理一个消息,没有并发,怎么提高性能;如果actor只能更改状态或行为,发消息给其他actor,创建有限数量的子actor,那我的业务逻辑在哪里;actor之间只能通过消息通信,我怎么知道另外一个actor的地址。其实吧,如果你能问到这几个问题,那么恭喜你,你非常需要我这个博客系列,我会一一进行分析,把我之前的坑展示给你看,以确保你不会再掉进去。

  其实Actor模型出现的很早,而20世纪80年代,爱立信在Erlang中实现了Actor模型,用于嵌入式电信应用程序。该实现中引入了监督机制提供的容错性概念。爱立信使用Erlang和Actor模型实现了一款日后经常被提及的应用:AXD301。这玩意儿能提供99.9999999% 的可用性,看到没,7个9!!!绝对可以亮瞎人们的狗眼,这意味着在100年的时间中,AXD301只有3.1秒的时间会宕机。

  Actor模型的另一个重要的特性就是容错,它通过监督机制提供容错。这跟java中的throw exception有点类似,都是把处理响应错误的责任交给出错对象以外的实体。但在java中如果一个程序或者线程抛出了一个异常,你敢放心的恢复对应的程序或线程吗?你确保恢复之后还能正常的运行吗,毕竟需要很多资源需要重新创建。但Actor模型可以!

  

  如上图所示actor之间是有层级关系的,子actor如果出现了异常会抛给父actor,父actor会根据情况重新构建子actor,子actor从出现异常,到恢复之后正常运行,这段时间内的所有消息都不会丢失,等恢复之后又可以处理下一个消息。也就是说如果一个actor抛出了异常,除了导致发生异常的消息外,任何消息都不会丢失。这容错性当然好了。当然了,为了实现这种特性,akka或者Erlang需要做很多工作的。

  Akka中的Actor模型还有另外一个比较重要的两个特性:分布式与位置透明性。其实可以认为这是一个特性。Actor模型中一个很重要的概念就是actor地址,因为其他actor需要通过这个地址与actor进行通信。akka考虑到分布式的网络环境,对actor地址进行了抽象,屏蔽了本地地址和远程地址的差异,对于开发者来说基本上是透明的。由于actor地址是透明的,那么akka有引入了集群。当然了基于Actor模型和位置透明性,Akka还有其他很多有用的组件,这里就不介绍了,后面会详细说明。

  关于Actor模型就先介绍到这里,下一章节我们会介绍Actor模型的最基本的设计模式,以说明该模型的适用场景。

akka设计模式系列(Actor模型)的更多相关文章

  1. akka设计模式系列-消息模型(续)

    在之前的akka设计模式系列-消息模型中,我们介绍了akka的消息设计方案,但随着实践的深入,发现了一些问题,这里重新梳理一下设计方法,避免之前的错误.不当的观点给大家带来误解. 命令和事件 我们仍然 ...

  2. akka设计模式系列-actor锚定

    actor锚定模式是指使用actorSelection对acor进行锚定的设计模式,也可以说是一个对actor的引用技巧.在某些情况下,我们可能需要能够根据Actor的path锚定对应的实例.简单来说 ...

  3. akka设计模式系列-消息模型

    通过前面的文章我们总结了几个常见的actor设计模式,但此处不得不提前介绍一下在Akka中消息的设计模式.随着对Akka的使用,我们会发现,使用Akka设计系统其实就是面向消息编程.actor之间消息 ...

  4. akka设计模式系列

    由于本人爱好Scala,顺便也就爱好Akka,但目前网上对Akka的介绍大多都是概念上或技术方向上的介绍,基本没有Akka设计模式或者Actor模型设计模式的资料.这对于Akka的普及非常不利,因为即 ...

  5. akka设计模式系列-慎用ask

    慎用ask应该是Akka设计的一个准则,很多时候我们应该禁用ask.之所以单独把ask拎出来作为一篇博文,主要是akka的初学者往往对ask的使用比较疑惑. "Using ask will ...

  6. Akka简介与Actor模型

    Akka是一个构建在JVM上,基于Actor模型的的并发框架,为构建伸缩性强,有弹性的响应式并发应用提高更好的平台.本文主要是个人对Akka的学习和应用中的一些理解. Actor模型 Akka的核心就 ...

  7. akka设计模式系列-While模式

    While模式严格来说是while循环在Akka中的合理实现.while是开发过程中经常用到的语句之一,也是绝大部分编程语言都支持的语法.但while语句是一个循环,如果循环条件没有达到会一直执行wh ...

  8. Akka简介与Actor模型(一)

    前言...... Akka是一个构建在JVM上,基于Actor模型的的并发框架,为构建伸缩性强,有弹性的响应式并发应用提高更好的平台.本文主要是个人对Akka的学习和应用中的一些理解. Actor模型 ...

  9. akka设计模式系列-Backend模式

    上一节我们介绍了Akka使用的基本模式,简单点来说就是,发消息给actor,处理结束后返回消息.但这种模式有个缺陷,就是一旦某个消息处理的比较慢,就会阻塞后面所有消息的处理.那么有没有方法规避这种阻塞 ...

随机推荐

  1. How to read and write multiple files in Python?

    Goal: I want to write a program for this: In a folder I have =n= number of files; first read one fil ...

  2. [模拟赛FJOI Easy Round #2][T3 skill] (最小割+最大权闭合子图(文理分科模型))

    [题目描述] 天上红绯在游戏中扮演敏剑,对于高攻击低防御的职业来说,爆发力显得非常重要,为此,她准备学习n个技能,每个技能都有2个学习方向:物理攻击和魔法攻击.对于第i个技能,如果选择物理攻击方向,会 ...

  3. 【Codeforces 140C】New Year Snowmen

    [链接] 我是链接,点我呀:) [题意] 题意 [题解] 每次都选择剩余个数最多的3个不同数字组成一组. 优先消耗剩余个数多的数字 这样能尽量让剩余的数字总数比较多,从而更加可能得到更多的3个组合 [ ...

  4. [luoguP1196] 银河英雄传说(并查集)

    传送门 记录 up[x] 表示 x 上方有多少个 all[x] 表示当前连通的有多少个 find 的时候 和 合并的时候 更新一下即可 ——代码 #include <cstdio> #in ...

  5. RSA的共模攻击

    实验吧题目:http://www.shiyanbar.com/ctf/1834 参考:http://hebin.me/2017/09/07/%e8%a5%bf%e6%99%aectf-strength ...

  6. noip模拟赛 enc

    [问题背景]zhx 和他的妹子聊天.[问题描述]考虑一种简单的加密算法.假定所有句子都由小写英文字母构成, 对于每一个字母, 我们将它唯一地映射到另一个字母. 例如考虑映射规则:a->b, b- ...

  7. 转载 - Vim 的 Python 编辑器详细配置过程 (Based on Ubuntu 12.04 LTS)

    出处:http://www.cnblogs.com/ifantastic/p/3185665.html Vim 的 Python 编辑器详细配置过程 (Based on Ubuntu 12.04 LT ...

  8. [codeVS3943] 数学奇才琪露诺

    题目描述 Description 作为上白泽慧音老师的出色弟子,数学奇才琪露诺在算术方面有很深的造诣.今天,codevs有幸请到了这位数学界的奇葩作为本场考试的第一题主考官. 琪露诺喜欢0-9之间的数 ...

  9. 好不容易帮同事写的一个awk,要记下来

    给昌哥写的过滤的东东. 是实现了,但感觉丑,不规范. 记得下先. 原始数据格式: -- :: [ pool--thread-: ] - [ DEBUG ] origin match ::, user: ...

  10. 1.4 - OSPF的运行模式⑦

    帧中继的子接口选用原则: 1.在一个封装FR的物理接口上,可以同时承载多条PVC. 为了网络的可扩展性,建议不论在考试环境还是在工程环境中,都应该优先考虑使用子接口 2.应该创建几个子接口:在一个物理 ...