Akka中Actor介绍《seventeen》译

What is an Actor?

上一节关于Actor Systems的部分解释了actor如何造成层次结构,而且是构建应用程序时的最小单元。本节将单独查看一个这样的actor,解释在实现它时的概念。有关全部细节的更深刻参考,请参阅Actorshtml

Actor是State,Behavior,Mailbox,Child Actors和Supervisor Strategy的容器。全部这些都封装在Actor Reference以后。一个值得注意的方面是演员有一个明确的生命周期,当再也不被引用时它们不会被自动销毁;在建立一个以后,您有责任确保它最终也会被终止 - 这也能够控制当Actor终止时如何释放资源。算法

Actor Reference

以下所述,须要从外部屏蔽actor对象以便从actor模型中受益。所以,使用actor Reference将actor表示到外部使用,actor Reference是能够自由且无限制地传递的对象。这分为内部和外部对象,能够实现全部所需操做的透明性:从新启动actor而无需在其余地方更新引用,将实际的actor对象放在远程主机上,向彻底不一样的应用程序中的actor发送消息。但最重要的方面是,除非演员自己不明智地发布这些信息,不然没法查看演员内部并从外部获取其状态。并发

State

Actor对象一般包含一些反映actor可能处于的状态的变量。这能够是显式状态机(例如使用FSM模块),也能够是计数器,监听器集,待处理请求等。这些数据是让演员有价值的东西,必须保护他们免受其余演员的腐败。好消息是,Akka Actor在概念上每一个都有本身的轻量级线程,彻底屏蔽了系统的其余部分。这意味着您没必要使用锁来同步访问,而是能够编写您的actor代码而没必要担忧并发性。异步

在幕后,Akka将在一组真实线程上运行多组actor,一般许多actor共享一个线程,而且一个actor的后续调用最终可能会在不一样的线程上进行处理。Akka确保此实现细节不会影响处理actor状态的单线程。函数

由于内部状态对于Actor的操做相当重要,因此具备不一致的状态是致命的。所以,当actor失败并由其主管从新启动时,将从头开始建立状态,就像首次建立actor同样。这是为了实现系统自我修复的能力。测试

经过持久保存收到的消息并在从新启动后重放它们,能够自动将actor的状态恢复到重启前的状态(请参阅“ Persistence”)。编码

Behavior

每次处理消息时,都会根据actor的当前behavior进行匹配。behavior是指定义在该时间点对消息做出反应的动做的函数,例如,若是客户端被受权则转发请求,不然拒绝它。此行为可能会随时间而改变,例如由于不一样的客户端会随着时间的推移得到受权,或者由于参与者可能会进入“服务中断”模式并稍后返回。这些更改是经过在状态变量中对它们进行编码来实现的,这些状态变量是从行为逻辑中读取的,或者函数自己能够在运行时被换出,请参阅变为和不成熟的操做。可是,在构造actor对象期间定义的初始行为是特殊的,由于从新启动actor会将其行为重置为此初始行为。spa

Mailbox

Actor的目的是处理消息,这些消息从其它Actor(或Actor系统外部)发送。链接发送者和接收者的片断是Actor的邮箱:每一个Actor只有一个邮箱,全部发件人都将其邮件排入队列。入队以发送操做的时间顺序发生,这意味着因为跨线程分配actor的明显随机性,从不一样的actor发送的消息可能在运行时没有定义的顺序。另外一方面,从同一个actor向同一目标发送多个消息将以相同的顺序排列它们。线程

有不一样的邮箱实现可供选择,默认为FIFO:由actor处理的消息的顺序与它们排队的顺序相匹配。这一般是一个很好的默认设置,但应用程序可能须要优先处理某些消息而不是其余消息。在这种状况下,优先级邮箱不会老是排在最后,而是排列在消息优先级给定的位置,甚至可能位于前面。在使用这样的队列时,处理的消息的顺序天然会由队列的算法定义,而且一般不是FIFO。htm

Akka与其余一些actor模型实现的不一样之处在于,当前行为必须始终处理下一个出列的消息,没有扫描邮箱以查找下一个匹配的消息。没法处理消息一般会被视为失败,除非覆盖此行为。

Child Actors

每一个Actor均可能是一个主管:若是它建立子任务来委派子任务,它将自动监督它们。子项列表保存在actor的上下文中,而且actor能够访问它。经过建立(context.actorOf(...))或中止(context.stop(child))子项来完成对列表的修改,并当即反映这些操做。实际的建立和终止操做以异步方式在幕后发生,所以它们不会“阻止”他们的主管。

Supervisor Strategy

Actor的最后一部分是处理其子女故障的策略。而后,Akka透明地完成故障处理,对每一个进入的故障应用监督和监控中描述的策略之一。因为此策略是Actor系统结构的基础,所以一旦建立了Actor,就没法更改。

考虑到每一个Actor只有一个这样的策略,这意味着若是不一样的策略适用于一个Actor的各个孩子,那么这些孩子应该被分组在具备匹配策略的中间监督者之下,再次优先考虑Actor系统的结构。将任务拆分为子任务。

When an Actor Terminates

一旦一个actor终止,自行中止或被其主管中止,它将释放其资源,将全部剩余的消息从其邮箱中排放到系统的“死信邮箱”中。将它们做为DeadLetters转发到EventStream。而后,使用系统邮箱在actor引用中替换邮箱,将全部新消息重定向到EventStream做为DeadLetters。尽管如此,这是在尽力而为的基础上完成的,所以不要依赖它来构建“保证交付”。

不只仅是默默地转储消息的缘由受到了咱们的测试的启发:咱们在转发死信的事件总线上注册了TestEventListener,而且会在收到的每封死信中记录警告 - 这对解密颇有帮助更快地测试失败。能够想到,该特征也可用于其余目的。

相关文章
相关标签/搜索