# Actor 系统
Actor 是封装状态和行为的对象，它们通过交换放在收件人邮箱中的消息进行专门的通信。从某种意义上说，Actor 是面向对象编程最严格的形式，但最好将其视为“人”：当与 Actor 一起建模解决方案时，设想一组人员并为其分配子任务，将其功能安排到组织结构中，并考虑如何升级失败（所有这些都得益于非实际地与人打交道，这意味着我们不需要关心他们的情感状态或道德问题）。结果可以作为构建软件实现的一个心理脚手架（`mental scaffolding`）。

- **注释**：`ActorSystem`是一个重量级架构，它将分配`1 … N`个线程，因此为每个逻辑应用程序都创建一个线程。

## 层次结构
就像在经济组织中一样，Actor 自然形成等级制度。一个负责监督程序中某个函数的 Actor 可能希望将其任务拆分为更小、更易于管理的部分。为此，它启动了由它监督的子 Actor。在「[这里](https://codechina.csdn.net/monokai/akka-guide/blob/master/articles/general-concepts/supervision.md)」解释监督细节的同时，我们将集中讨论本节中的基本概念。唯一的先决条件是要知道每个 Actor 只有一个监督者，这就是创建它的 Actor。

Actor 系统的典型特征是，任务被拆分和委托，直到它们变得足够小，可以一块处理。这样做，不仅任务本身结构清晰，而且结果 Actor 可以根据他们应该处理哪些消息、应该如何正常反应以及应该如何处理失败来进行推理。如果一个 Actor 没有处理特定情况的方法，它会向其监督 Actor 发送相应的失败消息，请求帮助。然后，递归结构允许在正确的级别处理故障。

将其与易于转入防御编程（`defensive programming`）的分层软件设计进行比较，目的是不泄漏任何故障：如果问题传达给了正确的人，那么可以找到比试图将所有事情“隐藏”在“地毯下”更好的解决方案。

现在，设计这样一个系统的困难在于如何决定谁应该监督什么。没有单一的最佳解决方案，但有一些指导方针可能会有所帮助：

- 如果一个 Actor 管理另一个 Actor 正在做的工作，例如通过传递子任务，那么管理 Actor 应该监督子 Actor。原因是管理 Actor 知道预期的故障类型以及如何处理。
- 如果一个 Actor 携带非常重要的数据（即，如果可以避免，其状态不会丢失），则该 Actor 应向其监督的子 Actor 找出任何可能危险的子任务，并处理这些子 Actor 的故障。根据请求的性质，最好为每个请求创建一个新的子级，这样可以简化收集答复的状态管理。这就是 Erlang 的“错误内核模式”。
- 如果一个 Actor 依靠另一个 Actor 来履行职责，它应该观察另一个 Actor 的活动，并在接到终止通知后采取行动。这与监督不同，因为监督方对监督策略没有影响，应该注意的是，单独的功能依赖性并不是决定将某个子 Actor 放在层级中何处的标准。

这些规则总是有例外的，但是不管你是遵守规则还是违反规则，你都应该有一个理由。

## 配置容器

Actor 系统作为 Actor 的协作集合，是管理共享设施（如调度服务、配置、日志记录等）的自然单元。具有不同配置的多个 Actor 系统可以在同一个 JVM 中共存，没有问题，Akka 本身没有全局共享状态。将其与一个节点内或通过网络连接的 Actor 系统之间的透明通信结合起来，可以看到 Actor 系统本身可以用作功能层次结构中的构建块。

## Actor 最佳实践

 1. Actor 应该像好的同事一样：高效地工作，而不是不必要地打扰其他人，并且避免占用资源。翻译成编程语言，这意味着以事件驱动的方式处理事件并生成响应（或更多请求）。Actor 不应在可能是锁、网络套接字等外部实体上阻塞，即占用线程时被动等待，除非这是不可避免的；对于后一种情况，请参见下文。
 2. 不要在 Actor 之间传递可变对象。为了确保这一点，最好选择不可变的消息。如果通过将它们的可变状态暴露到外部来破坏 Actor 的封装，则会返回正常的 Java 并发域，并存在所有的缺点。
 3. Actor 被设计成行为和状态的容器，接受这一点意味着不经常在消息中发送行为（使用 Scala 闭包可能很诱人）。其中一个风险是不小心在 Actor 之间共享可变状态，而这种对 Actor 模型的违反不幸地破坏了所有属性。
 4. 顶级 Actor 是错误内核的最核心部分，因此要谨慎地创建它们，并且更倾向于真正的分层系统。这对于故障处理（同时考虑配置的粒度和性能）有好处，而且它还减少了对守护者 Actor 的压力，如果使用过度，这是一个单一的竞争点。

## 你不应该关心的事
Actor 系统管理配置使用的资源，以便运行其包含的 Actor。在一个这样的系统中，可能有数百万的 Actor，毕竟所有的赞歌（`mantra`）都是将他们视为丰富的，并且他们在每个实例的开销只有大约 300 字节。当然，在大型系统中处理消息的确切顺序不受应用程序作者的控制，但这也是无意的。

## 终止 ActorSystem

当你知道应用程序的所有操作都已完成时，可以调`ActorSystem`的`terminate`方法。这将停止守护者 Actor，而守护者 Actor 又将递归地停止其所有子 Actor，即系统守护者。

如果要在终止`ActorSystem`时执行某些操作，请查看「[协调关闭](https://codechina.csdn.net/monokai/akka-guide/blob/master/articles/actors/actors.md#%E5%8D%8F%E8%B0%83%E5%85%B3%E9%97%AD)」。

----------

**英文原文链接**：[Actor Systems](https://doc.akka.io/docs/akka/current/general/actor-systems.html).


----------
———— ☆☆☆ —— [返回 -> Akka 中文指南 <- 目录](https://codechina.csdn.net/monokai/akka-guide/blob/master/README.md) —— ☆☆☆ ————