二 Akka学习 - actor介绍

一个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的并发之间提供一座桥梁

原文地址:https://www.cnblogs.com/liufei1983/p/8425759.html

时间: 2024-10-13 14:02:48

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

一 Akka学习 - actor

(引用 http://shiyanjun.cn/archives/1168.html) 一: 什么是Akka? Akka是JAVA虚拟机JVM平台上构建高并发.分布式和容错应用的工具包和运行时,是一个框架.Akka用Scala语言写成,同时提供了Scala和JAVA的开发接口. Akka处理并发的方法基于Actor模型.在Akka里,Actor之间通信的唯一机制就是消息传递. 二: 什么是Actor? 维基百科这样定义Actor模型: 在计算科学领域,Actor模型是一个并行计算(Concurr

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

学习使用AKKA 断断续续有一年了.目前还是习惯用java来写akka下面的程序.对于原生的scala还是没有时间和兴趣去学习它. 毕竟学习一门语言需要兴趣和时间的. AKKA学习资源还是不算丰富. 看过最多的就是官方的编程手册,还有就是AKKA Essentials 这两本.  自己动手写的程序还不算多,也放在github上面. 另外,在akka编译配置.升级版本上,以及部署多台服务器组建akka cluster 方面花费了不少时间.因为项目需要,上周重新在办公室用两台mac台式机和一台thi

(转)Akka学习笔记

Akka学习笔记系列文章: <Akka学习笔记:ACTORS介绍> <Akka学习笔记:Actor消息传递(1)> <Akka学习笔记:Actor消息传递(2)> <Akka学习笔记:日志> <Akka学习笔记:测试Actors> <Akka学习笔记:Actor消息处理-请求和响应(1) > <Akka学习笔记:Actor消息处理-请求和响应(2) > <Akka学习笔记:ActorSystem(配置)> &l

Akka学习——术语和概念

(大部分为翻译) Concurrency vs. Parallelism 并发 vs 并行 并发并不一定同时运行,比如使用时间片,使得两个任务交替执行.而并行是执两个任务真正的同时执行. Asynchronous vs. Synchronous   同步 vs 异步   如果一个方法被调用后,调用者只能等到此方法返回值或抛出异常才能继续前进,那这个方法就被称为是"同步"的. 而"异步"调用,是指调用者在经历有限的步骤之后,可以继续前进.方法的完成可以通过其它的机制进

MongooooooooooooooooooooDB入门二:基本概念介绍

前言 工欲善其事必先利其器.在学习MongoDB之前,需要对MongoDB的一些基本概念有系统的了解. 所以,本篇文章主要介绍MongoDB的一些基本概念,这些概念的定义均来自<MongoDB权威指南>,关于此书想要了解更多,请点击此处. 我尽量使用最简洁的语言来尽可能完整地描述这些基本概念,如有遗漏或不妥之处欢迎指正. 文档 文档是MongoDB的核心概念之一.多个键值对有序地放在一起便是文档.例如: {"name":"Jerry","sco

javaweb学习总结(三十二)——JDBC学习入门【转】

原文地址:javaweb学习总结(三十二)——JDBC学习入门 一.JDBC相关概念介绍 1.1.数据库驱动 这里的驱动的概念和平时听到的那种驱动的概念是一样的,比如平时购买的声卡,网卡直接插到计算机上面是不能用的,必须要安装相应的驱动程序之后 才能够使用声卡和网卡,同样道理,我们安装好数据库之后,我们的应用程序也是不能直接使用数据库的,必须要通过相应的数据库驱动程序,通过驱动程序去和数 据库打交道,如下所示: 1.2.JDBC介绍 SUN公司为了简化.统一对数据库的操作,定义了一套Java操作

Java基础知识二次学习-- 第一章 java基础

基础知识有时候感觉时间长似乎有点生疏,正好这几天有时间有机会,就决定重新做一轮二次学习,挑重避轻 回过头来重新整理基础知识,能收获到之前不少遗漏的,所以这一次就称作查漏补缺吧!废话不多说,开始! 第一章  JAVA简介 时间:2017年4月24日10:23:32 章节:01章_02节 内容:jdk的配置与安装 完成情况:已经完成,cmd中javac提示出相关命令 时间:2017年4月24日10:30:39 章节:01章_04节 内容:输出HelloWorld 完成情况: 已经完成 javac先将

设计模式(二)学习----动态代理

动态代理:动态代理是指在实现阶段不需要关心代理谁,而在运行阶段才指定代理哪一个对象.Spring AOP采用的核心思想就是动态代理设计模式.  下面看动态代理的UML类图: 下面思考问题:invocationHandler的invoke方法是由谁来调用的,代理对象是怎么生成的? 动态代理类: package com.lp.ecjtu.DynamicProxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect

《Linux内核设计与实现》第一、二章学习笔记

<Linux内核设计与实现>第一.二章学习笔记 姓名:王玮怡  学号:20135116 第一章 Linux内核简介 一.关于Unix ——一个支持抢占式多任务.多线程.虚拟内存.换页.动态链接和TCP/IP网络的现代化操作系统 1.主要发展过程   1969年,贝尔实验室的程序员们设计了一个文件系统原型,最终发展演化成了Unix 1971年,Unix被移植到PDP-11型机中 1973年,整个Unix系统使用C语言进行重写,为后来Unix系统的广泛移植铺平了道路 Unix第六版(V6)被贝尔实