一个actorSystem 是一个重量级的结构。它会分配N个线程。所以对于每一个应用来说只用创建一个ActorSystem。

Actor是种可怜的“生物”,它们不能独自存活。Akka中的每一个Actor都是由一个Actor系统(Actor System)来创建和维护的。一个Actor系统会提供一整套辅助功能,

树形结构

actors以树形结构组织起来,类似一个生态系统。例如,一个actor可能会把自己的任务划分成更多更小的、利于管理的子任务。为了这个目的,它会开启自己的子actor,并负责监督这些子actor。关于监督的具体细节就不在这里讨论了。我们只要知道一点,就是每一个actor都会有一个监督者,那就是创建这些actor的那个actor。

如下图:

actor系统的精华就是任务的分解。任务要被分割的要足够小,每个分片都会被委托给子actor。这里用到的思想很明显就是“分而治之”,万变不离其宗啊!要想做好这一切,不仅仅要把任务组织的非常清晰(利于分解),也要对处理任务的最终actor在以下方面进行考虑:哪些消息需要处理、如何正常的回应、如何处理失败等等。如果一个处理特定任务的actor失败了,它会向它的监督者发出响应错误的消息去寻求错误处理的方法。这种递归式(监督者也有自己的监督者)的结构可以保证错误在合适的级别上进行处理。

你的应用程序是由几十个还是几百万个Actor来组成取决于你的用例,但是Akka完全有能力处理百万级别数量的Actor,你可能觉得创建这么多Actor一定是疯了,但实际上,Actor和线程之间并不是一一对应的关系,这一点非常重要,否则系统的内存很快就会被耗光的。由于Actor的非阻塞特性,一个线程可以为不同的Actor服务,Akka(译者注:具体地说是Dispatcher)会让线程在不同的Actor之间切换,依据是当前谁有消息需要被处理就分配线程给它。为了了解实际发生了什么。

消息的发送和处理完成是一个异步的非阻塞的过程。发送方不会一直被阻塞到接收方处理完消息,它会直接继续它自己的工作,发送方可能会期望从处理方那里得到一个反馈消息,但也许它根本不关心消息的处理结果。当某些组件发送一条消息给一个Actor时,真正发生的事情是:这个消息被投递给了这个Actor的Mailbox, 我们基本上可以把Mailbox当成一个对列。把一条消息放到一个Actor的Mailbox的过程也是非阻塞的,比如:发送方不会一直等待消息进入接收方的Mailbox对列。

Dispatcher会通知Actor它的Mailbox有一条新消息,如果这个Actor正在处理着手头上的消息,Dispatcher会从当前的执行上下文里选一个可用的线程,一旦Actor处理完前面的消息,它会让Actor在这个准备好的线程上从Mailbox里取出这条消息去处理。Actor会阻塞分配给它的线程直到它开始处理一条消息,但这并不会阻塞消息的发送方,这意味着一个耗时较长的操作会影响整体的性能,因为所有其他的Actor不得不被安排从剩余线程中选取一个去处理消息(译者注:增加了线程调度的开销)。

因此,你的Receive偏函数要遵从一个核心的准则:尽可能地缩短它的执行时间(译者注:可以把任务分解为更小的单元委派更粒度更细的Actor去执行)。更重要的是,在你的消息处理代码里尽量地避免调用会造成阻塞的代码。当然,有些事情是你无法完全避免的,比如,当今主流的数据库驱动基本都是阻塞的,如果你想让你的程序基于Actor去持久化或查询数据时,你就会面临这样的问题。现在已经有一些应对这类问题的方案了,但是作为一偏介绍性的文章,本文先不涉及。

如何创建一个actor实例?  

用new方法?这样不行!Akka会用一个ActorInitializationException异常回敬你。事情是这样的:为了能让Actor良好地工作,你的Actor必须交给ActorSystem和它的组件来托管。因此,你需要通过ActorSystem来帮你创建这个实例

定义在AcotorSysytem上actorOf方法期望一个Props实例,针对新建的Actor的配置信息都会封装到这个Props实例里,

注意:actorOf返回的对象类型不是Barista而是ActorRef(译者注:Akka对Actor的托管体现在很多地方,前面提到的你不能直接创建一个Actor实例是一方面,此处,创建之后你得到的也不是Actor实例本身而是一个ActorRef)。Actor从不会与其他Actor直接通信,因此没有必要获取一个Actor实例的直接引用,而是让Actor或其他组件获取那些需要发送消息的Actor的ActorRef

因此,ActorRef扮演了Actor实例代理的角色,这样做会带来很多好处,因为一个ActorRef可以被序列化,我们可以让它代理一个远程机器上的Actor,至于ActorRef后面的这个Actor是本地JVM里的还是一个远程机器上的,这对使用者来说都是透明的,我们把这种特性称作“位置透明”。

请记住,ActorRef不是类型参数化的,任何ActorRef都可以互相交换,以便可以让你发送任意的消息给任意的ActorRef。这种设计我们前面也提到了,它让你可以简单地修改你的Actor系统的网络拓扑而不需要对发送方做任何修改。

问询(Ask)机制:

有时候,给一个Actor发送消息然后期待返回一个响应消息这种模式并不适用于某些场景,最常见的例子是当某些组件并不是Actor但又需要和Actor交互时,它们就无法接收来自Actor的消息。对于这种情况,Akka有一种Ask机制,它在基于Actor的并发和基于Future的并发之间提供一座桥梁.

定义一个actor:
在Java里面,角色是通过继承UntypedActor 类及实现onReceive方法来实现的.这个方法将message作为参数。
Props:

用Props创建角色:
final ActorRef testActor = system.actorOf(Props.create(ProduceActor.class));

发送信息:
向actor发送消息是使用下列方法之一。

意思是“fire-and-forget”, e.g. 异步发送一个消息并立即返回。也称为 tell.
异步发送一条消息并返回一个 Future代表一个可能的回应。也称为 ask.

接收信息:
当一个角色收到被传递到onReceive方法的消息

转发消息:
你可以将消息从一个角色转发给另一个。虽然经过了一个‘中转’,但最初的发送者地址/引用将保持不变。当实现功能类似路由器、负载均衡器、备份等的角色时会很有用。同时你需要传递你的上下文变量。
target.forward(result, getContext());

回复信息
如果你需要一个用来发送回应消息的目标,可以使用 getSender, 它是一个角色引用。 你可以用 getSender().tell(replyMsg, getSelf())向这个引用发送回应消息。
你也可以将这个ActorRef保存起来将来再作回应。如果没有sender (不是从actor发送的消息或者没有future上下文) 那么 sender 缺省为 ‘死信’ 角色的引用。

supervisorActor.tell(akka.actor.PoisonPill.getInstance(), ActorRef.noSender());
ctorSystem.terminate();

PoisonPill:
你也可以向角色发送 akka.actor.PoisonPill 消息, 这个消息处理完成后角色会被终止。 PoisonPill 与

杀死一个角色:
victim.tell(akka.actor.Kill.getInstance(), ActorRef.noSender());

二 Akka学习 - actor介绍的更多相关文章

  1. 三 akka学习 actor的例子

    (转载: http://blog.csdn.net/chenleixing/article/details/44044243 ) Java并发编程的4种风格:Threads,Executors,For ...

  2. 一 Akka学习 - actor

    (引用 http://shiyanjun.cn/archives/1168.html) 一: 什么是Akka? Akka是JAVA虚拟机JVM平台上构建高并发.分布式和容错应用的工具包和运行时,是一个 ...

  3. (转)Akka学习笔记(二):Actor Systems

    Akka学习笔记(二):Actor Systems 图中表示的是一个Actor System,它显示了在这个Actor System中最重要实体之间的关系. 什么是actor,是一个封装了状态和行为的 ...

  4. Redis总结(五)缓存雪崩和缓存穿透等问题 Web API系列(三)统一异常处理 C#总结(一)AutoResetEvent的使用介绍(用AutoResetEvent实现同步) C#总结(二)事件Event 介绍总结 C#总结(三)DataGridView增加全选列 Web API系列(二)接口安全和参数校验 RabbitMQ学习系列(六): RabbitMQ 高可用集群

    Redis总结(五)缓存雪崩和缓存穿透等问题   前面讲过一些redis 缓存的使用和数据持久化.感兴趣的朋友可以看看之前的文章,http://www.cnblogs.com/zhangweizhon ...

  5. 2014.8.12-AKKA和Actor model 分布式开发环境学习小结

    学习使用AKKA 断断续续有一年了. 眼下还是习惯用java来写akka以下的程序.对于原生的scala还是没有时间和兴趣去学习它. 毕竟学习一门语言须要兴趣和时间的. AKKA学习资源还是不算丰富. ...

  6. AKKA学习(二) 未完

    Actor调用 从上面的例子中,我们可以大概的对AKKA在JAVA中的使用有一个全局的概念.这里我们在稍微细致的讲解一下. 在JAVA中使用AKKA进行开发主要有这几个步骤: 定义消息模型. 创建Ac ...

  7. AKKA学习笔记

    AKKA学习笔记总结 01. AKKA 1. 介绍: Akka基于Actor模型,提供了一个用于构建可扩展的(Scalable).弹性的(Resilient).快速响应的(Responsive)应用程 ...

  8. (转)Akka学习笔记

    Akka学习笔记系列文章: <Akka学习笔记:ACTORS介绍> <Akka学习笔记:Actor消息传递(1)> <Akka学习笔记:Actor消息传递(2)> ...

  9. 翻译:AKKA笔记 - Actor消息 -1(一)

    从第一篇Akka笔记的介绍中,我们是从很高的高度去观察Akka工具箱中的Actors.在这篇笔记的第二篇,我们会看一下Actors中的消息部分.而且延续上一次的例子,我们还会使用同样的学生与老师的例子 ...

随机推荐

  1. Meeting-in-the-Middle (LA 2965)

    Meeting-in-the-Middle,又称“中途相遇法”.准确地说,它只是一种策略. 顺便说一下,这个算法真的很冷门! 结合这道题来讨论一下吧:LA 2965.ε(┬┬﹏┬┬)3 因为博主的英文 ...

  2. Django 动态导入配置文件的类

    导入配置文件的类 #如何用字符串的形式动态导入模块 from importlib import import_module path=''api.cors.CORSMiddleware' #CORSM ...

  3. 怎样将lua移植到arm平台的linux内核

    将脚本移植到内核是一件非常酷的事情,lua已经被移植到NetBSD的内核中,也有一个叫lunatik的项目把lua移植到了linux内核.仅仅可惜仅仅支持x86.不支持arm,在网上搜索了下,没有找到 ...

  4. antd-mobile的例子--cnode

    antd-mobile    简单的例子 预览地址 https://shenggen1987.github.io/antd-mobile-roadhog/#/crm/pages/users githu ...

  5. 如何在JSTL中获取数组或者list对象的索引值(index)

    <c:forEach items="${productList}" var="products" varStatus="status" ...

  6. Swap file "/etc/.hosts.swp" already exists! [O]pen Read-Only, (E)dit anyway, (R)ecover, (D)elete it,

    非正常关闭vi编辑器时会生成一个.swp文件 非正常关闭vi编辑器时会生成一个.swp文件 关于swp文件 使用vi,经常可以看到swp这个文件,那这个文件是怎么产生的呢,当你打开一个文件,vi就会生 ...

  7. requests ip代理池单ip和多ip设置方式

    reqeusts库,在使用ip代理时,单ip代理和多ip代理的写法不同 (目前测试通过,如有错误,请评论指正) 单ip代理模式 省去headers等 import requests proxy = { ...

  8. maven 手动加载第三方jar、zip包

    使用maven搭建工程时,难免要加载大量的第三方的jar包.zip包比较少用,而maven的官网提供的jar往往不能满足需求,这时需要我们手动加载到我们本地或nexus私服的仓库中. 1.加载jar包 ...

  9. 算法(Algorithms)第4版 练习 2.3.25

      代码实现: public static void sort(Comparable[] a) { StdRandom.shuffle(a);//eliminate dependence on inp ...

  10. node.js+express+jade系列七:富文本编辑框的使用

    下载nicEdit富文本编辑框, 把nicEdit.js文件放到public/javascripts/下 新建jade文件:代码如下 doctype htmlhtml    head        t ...