一个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. 阿里云服务(一) OSS

    阿里电子商务迄今是中国最大的电商网站,各个厂商都在去模仿.就像google的大数据处理,Hadoop的思想等等,只有做出了一些成绩,起了带头羊,那么将会是非常吃香的.从今天开始简单学习了解一下阿里的各 ...

  2. scala与java之间的那些事

    scala与java之间的关系,我认为可以用一句话来开头:scala来源于java,但又高于java. scala的设计者Martin Odersky就是一个JAVA控,这位牛人设计了javac和编写 ...

  3. Java之线程池(二)

    关于线程和线程池的学习,我们可以从以下几个方面入手: 第一,什么是线程,线程和进程的区别是什么 第二,线程中的基本概念,线程的生命周期 第三,单线程和多线程 第四,线程池的原理解析 第五,常见的几种线 ...

  4. CSS3滑块菜单

    在线演示 本地下载

  5. ThinkPHP的Auth类认证

    Auth 类已经在ThinkPHP代码仓库中存在很久了,但是因为一直没有出过它的教程, 很少人知道它, 它其实比RBAC更方便 .  RBAC是按节点进行认证的,如果要控制比节点更细的权限就有点困难了 ...

  6. poj 2251 Dungeon Master-搜索进阶-暑假集训

    普及一下知识 s.empty() 如果栈为空返回true,否则返回falses.size() 返回栈中元素的个数s.pop() 删除栈顶元素但不返回其值s.top() 返回栈顶的元素,但不删除该元素s ...

  7. mysql分区partition

    分区后 会产生多个 数据存储文件MYD,MYI ,把内容读取分散到多个文件上,这样减少并发读取,文件锁的概率,提高IO === 水平分区的几种模式:===1. Range(范围) – 这种模式允许DB ...

  8. 算法(Algorithms)第4版 练习 2.2.11(3)

    关键代码实现: public static void sort(Comparable[] input) { int N = input.length; aux = input.clone();//mu ...

  9. 各种IoC框架下实现AOP

    .Net AOP(五) 各种IoC框架下实现AOP 利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率 主要功能 日志记录,性 ...

  10. js 处理移动端触摸事件

    在处理移动端的touch事件时,我们可以选择一些插件来处理,比如jquery ui touch punch.js 提供丰富的触摸效果,可以满足移动端的开发, 但是,有些移动端开发中,并不需要如此复杂的 ...