(转)http://www.csdn.net/article/2014-12-17/2823174

在Akka里面,和Actor通信的唯一方式就是通过ActorRefActorRef代表Actor的一个引用,可以阻止其他对象直接访问或操作这个Actor的内部信息和状态。消息可以通过一个ActorRef以下面的语法协议中的一种发送到一个Actor: 
-!(“告知”) —— 发送消息并立即返回 
-?(“请求”) —— 发送消息并返回一个Future对象,代表一个可能的应答

每个Actor都有一个收件箱,用来接收发送过来的消息。收件箱有多种实现方式可以选择,缺省的实现是先进先出(FIFO)队列。

在处理多条消息时,一个Actor包含多个实例变量来保持状态。Akka确保Actor的每个实例都运行在自己的轻量级线程里,并保证每次只处理一条消息。这样一来,开发者不必担心同步或竞态条件,而每个Actor的状态都可以被可靠地保持。

Akka的Actor API中提供了每个Actor执行任务所需要的有用信息:

  • sender:当前处理消息的发送者的一个ActorRef引用
  • context:Actor运行上下文相关的信息和方法(例如,包括实例化一个新Actor的方法ActorOf
  • supervisionStrategy:定义用来从错误中恢复的策略
  • self:Actor本身的ActorRef引用

再次需要注意的是,在Akka里,Actor之间通信的唯一机制就是消息传递。消息是Actor之间唯一共享的东西,而且因为多个Actor可能会并发访问同样的消息,所以为了避免竞态条件和不可预期的行为,消息的不可变性非常重要。

因为Case Class默认是不可变的并且可以和模式匹配无缝集成,所以用Case Class的形式来传递消息是很常见的。(Scala中的Case Class就是正常的类,唯一不同的是通过模式匹配提供了可以递归分解的机制)。

Akka的容错和监管者策略

在Actor系统里,每个Actor都是其子孙的监管者。如果Actor处理消息时失败,它就会暂停自己及其子孙并发送一个消息给它的监管者,通常是以异常的形式。

在Akka里面,监管者策略是定义你的系统容错行为的主要并且直接的机制。

在Akka里面,一个监管者对于从子孙传递上来的异常的响应和处理方式称作监管者策略。 监管者策略是定义你的系统容错行为的主要并且直接的机制。

当一条消息指示有一个错误到达了一个监管者,它会采取如下行动之一:

  • 恢复孩子(及其子孙),保持内部状态。 当孩子的状态没有被错误破坏,还可以继续正常工作的时候,可以使用这种策略。
  • 重启孩子(及其子孙),清除内部状态。 这种策略应用的场景和第一种正好相反。如果孩子的状态已经被错误破坏,在它可以被用到Future之前有必须要重置其内部状态。
  • 永久地停掉孩子(及其子孙)。 这种策略可以用在下面的场景中:错误条件不能被修正,但是并不影响后面执行的操作,这些操作可以在失败的孩子不存在的情况下完成。
  • 停掉自己并向上传播错误。 适用场景:当监管者不知道如何处理错误,就把错误传递给自己的监管者。

而且,一个Actor可以决定是否把行动应用在失败的子孙上抑或是应用到它的兄弟上。有两种预定义的策略:

  • OneForOneStrategy:只把指定行动应用到失败的孩子上
  • AllForOneStrategy:把指定行动应用到所有子孙上

如果没有指定策略,那么就使用如下默认的策略:

  • 如果在初始化Actor时出错,或者Actor被结束(Killed),那么Actor就会停止(Stopped)
  • 如果有任何类型的异常出现,Actor就会重启

Akka也考虑到对 定制化监管者策略的实现,但正如Akka文档也提出了警告,这么做要小心,因为错误的实现会产生诸如Actor系统被阻塞的问题(也就是说,其中的多个Actor被永久挂起了)。

本地透明性

Akka架构支持 本地透明性,使得Actor完全不知道他们接受的消息是从哪里发出来的。消息的发送者可能驻留在同一个JVM,也有可能是存在于其他的JVM(或者运行在同一个节点,或者运行在不同的节点)。Akka处理这些情况对于Actor(也即对于开发者)来说是完全透明的。唯一需要说明的是跨越节点的消息必须要被序列化。

Actor系统设计的初衷,就是不需要任何专门的代码就可以运行在分布式环境中。Akka只需要一个配置文件(Application.Conf),用以说明发送消息到哪些节点。下面是配置文件的一个例子:

  1. akka {
  2. actor {
  3. provider = "akka.remote.RemoteActorRefProvider"
  4. }
  5. remote {
  6. transport = "akka.remote.netty.NettyRemoteTransport"
  7. netty {
  8. hostname = "127.0.0.1"
  9. port = 2552
  10. }
  11. }
  12. }

最后的一些提示

我们已经了解了Akka框架帮助完成并发和高性能的方法。然而,正如这篇教程指出的,为了充分发挥Akka的能力,在设计和实现系统时,有些要点值得考虑:

  • 我们应尽最大可能为每个Actor都分配最小的任务(如上面讨论的,遵守单一职责原则)
  • Actor应该异步处理事件(也就是处理消息),不应该阻塞,否则就会发生上下文切换,影响性能。具体来说,最好是在一个Future对象里执行阻塞操作(例如IO),这样就不会阻塞Actor,如:
  1. case evt => blockingCall() // BAD
  2. case evt => Future {
  3. blockingCall()           // GOOD
  4. }
  • 要确认你的消息都是不可变的,因为互相传递消息的Actor都在它们自己的线程里并发运行。可变的消息很有可能导致不可预期的行为。
  • 由于在节点之间发送的消息必须是可序列化的,所以必须要记住消息体越大,序列化、发送和反序列化所花费的时间就越多,这也会降低性能。

Akka概念集的更多相关文章

  1. 使用Akka构建集群(一)

    概述 Akka提供的非常吸引人的特性之一就是轻松构建自定义集群,这也是我要选择Akka的最基本原因之一.如果你不想敲太多代码,也可以通过简单的配置构建一个非常简单的集群.本文为说明Akka集群构建的学 ...

  2. 使用Akka构建集群(二)

    前言 在<使用Akka构建集群(一)>一文中通过简单集群监听器的例子演示了如何使用Akka搭建一个简单的集群,但是这个例子“也许”离我们的实际业务场景太远,你基本不太可能去做这样的工作,除 ...

  3. akka 的集群访问方式

    akka  中采用startProxy分区代理 访问 ,跟使用shardRegion 来访问的区别 这两种访问方式是不是重了呢. 而另外这是一个单例代理 private fun startUniver ...

  4. Akka(11): 分布式运算:集群-均衡负载

    在上篇讨论里我们主要介绍了Akka-Cluster的基本原理.同时我们也确认了几个使用Akka-Cluster的重点:首先,Akka-Cluster集群构建与Actor编程没有直接的关联.集群构建是A ...

  5. Linux 集群概念 , wsgi , Nginx负载均衡实验 , 部署CRM(Django+uwsgi+nginx), 部署学城项目(vue+uwsgi+nginx)

    Linux 集群概念 , wsgi , Nginx负载均衡实验 , 部署CRM(Django+uwsgi+nginx), 部署学城项目(vue+uwsgi+nginx) 一丶集群和Nginx反向代理 ...

  6. Aaron Stannard谈Akka.NET 1.1

    Akka.NET 1.1近日发布,带来新特性和性能提升.InfoQ采访了Akka.net维护者Aaron Stannard,了解更多有关Akka.Streams和Akka.Cluster的信息.Aar ...

  7. Akka 简介与入门

    Akka 简介与入门 http://www.thinksaas.cn/group/topic/344095/ 参考官网  http://akka.io/ 开源代码  https://github.co ...

  8. Akka并发编程框架 -概念模型(Akka.net或者Orleans)

    Akka 来构建具备高容错性.可以横向扩展的分布式网络应用程序. Akka 通常是指一个强大的分布式工具集,用于协调远程计算资源来进行一些工作 Akka 工具集以及Actor 模型的介绍. Actor ...

  9. Akka源码分析-Cluster-DistributedData

    上一篇博客我们研究了集群的分片源码,虽然akka的集群分片的初衷是用来解决actor分布的,但如果我们稍加改造就可以很轻松的开发出一个简单的分布式缓存系统,怎么做?哈哈很简单啊,实体actor的id就 ...

随机推荐

  1. Java之static理解

    说到关键字static,首先想到了常量,静态变量,本文我总结了下static的用法. 1.静态变量 可以被赋值,便于类访问. 2.静态方法 静态方法与静态变量都可以被private.public修饰. ...

  2. [scrapy] scrapy 使用goose作为正文提取

    import scrapy from goose import Goose class Article(scrapy.Item): title = scrapy.Field() text = scra ...

  3. Codeforces 1099 D. Sum in the tree-构造最小点权和有根树 贪心+DFS(Codeforces Round #530 (Div. 2))

    D. Sum in the tree time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  4. Codeforces 1099 A. Snowball-暴力(Codeforces Round #530 (Div. 2))

    A. Snowball time limit per test 1 second memory limit per test 256 megabytes input standard input ou ...

  5. (7) go 函数

    1.格式 调用 2.包 (1)包 本质 文件夹.每一个文件都必须属于一个包 (2)给包取别名 (3)函数的首字母大小,决定是否能被外包访问 (3) 3.多返回值 4.递归 5.基本数据类型和数组都是拷 ...

  6. jsp页面中获取session中的值

    Jsp中获取Session: session是jsp的内置对象,所以你可以直接写在jsp的 <% session.setAttribute("a", b); //把b放到se ...

  7. JAX-WS文章汇总

    学习路线图 传送门 最简单的Web Service实现- 这里提供一个最简单的Web Service的实现,基于JAX-WS.除了jdk不需要任何其他jar包,使用Eclipse提供的Web Serv ...

  8. Ghostscript 中 ps2pdf 命令在 windows msys 下的运行错误问题。

    前两天看到了 miloyip/game-programmer 这个项目觉得特别有用,真是好东西,明确了指出了学习路线,尤其是新手.不过打开看,有些书对应的亚马逊链接是无效的,比如<Tricks ...

  9. 51nod 1201 (dp)

    整数划分 将N分为若干个不同整数的和,有多少种不同的划分方式,例如:n = 6,{6} {1,5} {2,4} {1,2,3},共4种.由于数据较大,输出Mod 10^9 + 7的结果即可.   In ...

  10. HZAU 1205 Sequence Number(双指针)

    题目链接:http://acm.hzau.edu.cn/problem.php?id=1205 [题意]给你一串数,要求你找到两个数a[i],a[j],使得a[i]<=a[j]且j>=i且 ...