Akka-doc-zh

位置透明性

上一节讲到了如何使用actor路径来实现位置透明性。这个特殊的功能需要额外的解释,因为“透明远程调用”在不同的上下文中(编程语言,平台,技术)有非常不同的用法。

默认分布式

Akka中所有的东西都是被设计为在分布式环境下工作的:actor之间所有的互操作都是使用纯粹的消息传递机制,所有的操作都是异步的。这些努力是为了确保其所有功能,无论是在单一的JVM上还是在拥有很多机器的集群里都能同样有效。实现这一点的关键是从远程到本地进行优化,而不是从本地到远程进行一般化。参阅这篇经典论文来了解关于为什么第二种方式注定要失败的详细讨论。

破坏透明性的方式

由于设计分布式执行过程对可以做的事情添加了一些限制,Akka所满足的约束并不一定在使用akka的应用程序中也满足。最明显的一条是网络上发送的所有消息都必须是可序列化的。而不那么明显的是,这也包括在远程节点上创建actor时,用作actor工厂的闭包(即在Props里)。

另一个结果是所有元素都需要知道所有交互是完全异步的,在一个计算机网络中这意味着一个消息可能需要好几分钟才能到达接收方(跟配置有关)。还意味着消息丢失的概率比在单一的JVM中高得多,接近0(仍不能完全保证!)。

远程调用如何使用?

我们把透明性的想法限制在“Akka中几乎没有为远程调用层设计的API”:而完全由配置来驱动。你只需要按照之前的章节概括的那些原则来编写你的应用,然后在配置文件里指定远程部署的actor子树。这样你的应用可以不用通过修改代码来实现扩展。API中唯一允许编程来影响远程部署的部分是Props包含的一个属性,这个属性可能被设为一个特定的 Deploy 实例;这与在配置文件中进行部署设置具有相同的效果(如果两者都有,那么配置文件优先)。

Peer-to-Peer vs. Client-Server

Akka Remoting是以对等网络方式进行actor系统连接的通信模块,它是Akka集群的基础。远程处理的设计取决于两个(相关)的设计决策:

  • 涉及系统之间的通信是对称的:如果系统A可连接到系统B,那么B系统必须也能够独立连接到系统A。
  • 通信系统中的角色按照连接的模式是对称的:不存在系统只接受连接,也没有系统只发起连接。

这些决定的结果是,它不可能按照预定义的角色安全地创建纯粹的“客户端-服务器”设置(违反假设2 ),对于“客户端-服务器”的设置,最好是使用HTTP或Akka I/O 。

使用设置涉及网络地址转换, 负载均衡器或 Docker容器违反假设1, 除非采取额外步骤, 让网络配置允许所涉及的系统双向通信。在这种情况下Akka能配置来绑定到不同的网络地址建立Akka节点之间的连接:

akka {
  remote {
    netty.tcp {
      hostname = my.domain.com      # external (logical) hostname
      port = 8000                   # external (logical) port
      bind-hostname = local.address # internal (bind) hostname
      bind-port = 2552              # internal (bind) port
    }
  }
}

使用路由来进行垂直扩展的标记点

一个actor系统除了可以在集群中的不同节点上运行不同的部分,还可以通过并行增加actor子树的方法来垂直扩展到多个cpu核上(例如搜索引擎并行处理不同的查询)。克隆出来的子树可以使用不同的方法来进行路由,例如循环(round-robin)。要达到这种效果,开发者仅需要声明一个“withRouter”的actor,这样系统会创建一个路由actor取而代之,该路由actor会按照期望类型和配置的数目生成子actor,并使用所配置的方式来对这些子actor进行路由。一旦声明了这样的路由,它的配置可以自由地被配置文件里的配置进行重写,包括把它与其(某些)子actor的远程部署进行混合。具体可参阅 路由器(Scala)路由器(Java)