以 Akka 为示例,介绍 Actor 模型

阅读数:17354 2014 年 11 月 3 日

许多开发者在创建和维护多线程应用程序时经历过各种各样的问题,他们希望能在一个更高层次的抽象上进行工作,以避免直接和线程与锁打交道。为了帮助这些开发者,Arun Manivannan编写了一系列的博客帖子,在目前总共六篇帖子中,他通过大量的图片及一些简单的Akka示例,解释了Actor 模型的原理,并进一步探索了 Akka 工具所提供的各种特性。

Arun 首先从整体上对 Actor 进行了介绍,他在示例中将 Actor 比作了一群人:

你可以将 Actor 当作是一群人,他们互相之间不会面对面地交流,而只是通过邮件的方式进行沟通。

传递消息是 Actor 模型的基础,Arun 以一名学生和一位教师举例,描述了以下基础流程:

  • 一名学生给一位教师发送了一封邮件,邮件一旦发送之后,就不能够修改了。
  • 该教师会在她认为适合的时机去检查她的邮箱,从而收到这封邮件。
  • 该教师稍后会寄一封回信给该学生,这封回信也是一旦发送就不可变的。
  • 该学生在一段时间后决定去检查一下他的邮箱,从而收到了回信,(他可没有一直守候在邮箱旁等待回信哦)。

如果信息是单向的,那么它一旦送出之后并不会期待或等待任何响应。除了这种情况之外,Actor 都能够在一个请求 - 响应周期内,为发送者发回一个响应消息。

接下来的示例讲解了并发的情况,示例中包含了多名学生和多位教师,每一名学生都会向所有教师发送邮件。这种情况与之前的示例并没有不同,因为每个参与者都分别拥有自己的邮箱,而且每封邮件都会按照它们到达邮箱的顺序被阅读。如果发生了某位教师不能接收邮件的情况,那么一位新的教师会替代他进行接收,从而实现故障转移。

一个 Actor 的生命周期并不复杂,首先通过构造函数进行创建,随后调用它的 preStart 方法,而 Actor 准备开始接收消息时,再调用它的 receive 方法。最后,调用 postStop 方法将 Actor 置为终结状态。Arun 还提到,Actor 的生命周期与一个 Java servlet 非常相似,仅存在着一些细微的差异。

Actor 之间的关系是层次结构型的,每个 Actor 都从属于另外一个 Actor。Arun 将这种结构与文件系统进行了比较,在文件系统中存在着一些顶层文件夹,而当你依照文件夹的层次结构进入内部时,文件夹的总数也在不断上升。通常来说,父 Actor 创建子 Actor 以处理一些子任务,或者是让子 Actor 在隔离的情况下去处理一些特别容易出错的任务,这样可以保证系统在故障发生时能够恢复状态。Actor 的容错性的关键部分来自于父 Actor 管理子 Actor 生命周期的能力。

Arun 还描述了一些其它方面的内容,包括日志记录、测试与配置。你可以从Github下载一个包含了完整源代码的示例项目。

除了用于 Java 与 Scala 的 Akka 项目之外,还有支持其它平台的 Actor 模型的实现,比如在.NET 平台下就存在着两种不同实现方式的 Actor 项目。

查看英文原文:An Introduction to Actor Model, with Examples in Akka