默认分布式
Akka中的所有内容都是在分布式环境中设计的:所有actor的交互都使用纯消息传递,而且一切都是异步的。 这项工作的目的是确保在单个JVM中或在数百台机器集群中运行时,所有功能都是同等可用的。 启用这一功能的关键是通过优化从远程到本地,而不是试图通过泛化从本地到远程。看见这篇经典论文详细讨论第二种方法必然会失败的原因。 该论文当然也是英文的,确实需要深究的可以看看。
与Akka通过优化从远程到本地,与之相对的是传统的RPC框架则是通过透明化远程处理的方式实现(使远程调用看起来和本地调用相同。如:Java RMI)
这属于两种选择
- 远程交互与本地交互采用相同的语义(理论上不可取,就是RMI这种,屏蔽了通信细节,调用者需要处理不确定的错误)
- 改变本地交互语义以适应远程通信的限制(过于激进,将本地与远程计算清楚的划分,并在代码中选择不同的表征)
对于Akka而言,调用者实际就是消息发送者,它不需要处理调用异常。 位置透明性的目标并不在于使远程交互看起来像本地交互,更多的是在本地和远程交互的通用抽象下统一对消息传递的表达。
破坏透明性的方式
对于使用Akka的应用程序来说,什么是真的并不一定是正确的,因为为分布式执行的设计会对可能发生的事情造成一些限制。 最明显的一点是,通过(网络)连线发送的所有消息都必须是可序列化的。 虽然不那么明显,但这包括closures,如果要在远程节点上创建actor,这些closures被用作actor工厂(即在Props)。这里不太理解closures是闭包还是啥意思。 通过网络传输的消息必须是支持序列化的这点,我想会更重要一些。
另一个重要性的问题是,每件事都需要知道所有的交互都是完全异步的,这在计算机网络中可能意味着一条消息到达收件人可能需要几分钟(取决于配置)。 这还意味着消息丢失的概率要比在一个JVM中高得多,JVM几乎为零(仍然:没有硬保证!)。这点在(Actor消息传递的可靠性)那说明了。
远程处理是如何使用的
我们认为透明性的概念是有限的,因为Akka的远程处理层几乎没有api:它完全是由配置驱动的。只需按照前面章节中概述的原则编写应用程序,然后在配置文件中指定actor子树的远程部署。 这样,您的应用程序就可以在不需要接触代码的情况下进行扩展。 API中唯一允许对远程部署产生编程影响的部分是,Props包含可以设置为特定Deploy实例的字段;这与将等效部署所需字段放入配置文件(如果两者都给定,配置文件优先)的效果相同。
点对点客户端服务器
Akka远程处理是一个以对等方式连接actor系统的通信模块,它是Akka集群的基础。远程处理的设计由两个(相关的)设计决策驱动:
- 相关系统之间的通信是对称的:如果系统A可以连接到系统B,那么系统B也必须能够独立地连接到系统A。
- 就连接模式而言,通信系统的作用是对称的:没有只接受连接的系统,也没有只启动连接的系统。
这些决定的结果是,不可能安全地创建具有预定义角色的纯客户端服务器设置(违反假设2)。对于客户端服务器设置,最好使用HTTP或Akka I/O。
重要:使用涉及网络地址转换、负载均衡或Docker容器的设置违反假设1,除非在网络配置中采取其他步骤以允许相关系统之间的对称通信。 在这种情况下,Akka可以被配置为绑定到不同于用于在Akka节点之间建立连接的网络地址。请看Akka behind NAT or in a Docker container.
用路由器放大的标记点
除了能够在集群的不同节点上运行actor系统的不同部分之外,还可以通过增加支持并行化的actor子树(例如,一个并行处理不同查询的搜索引擎)来扩展到更多的核心。 然后,复制的actor(原文是clones,并且这里Points被我写成标记点了,这里更像是原actor的化身)可以以不同的方式被路由到,例如,round-robin。 实现这一目标的唯一必要之处是,开发人员需要将某个actor声明为“withRouter”,然后–取而代之–将创建一个路由器actor,它将以配置的方式生成一个可配置数量的、具有所需类型和路由的子节点。 一旦声明了这样的路由器,就可以从配置文件中自由地覆盖它的配置,包括将它与(一些)子程序的远程部署混合起来。在路由中阅读更多有关此信息的内容。
- 使用搜狗翻译、百度翻译、谷歌翻译,仅供参考
- 来自官方文档、参考《响应式架构 消息模式Actor实现与Scala、Akka应用集成》
- 后续随着理解深入会继续修改错误和描述,以便更好理解,本博客开源,欢迎指出错误