Actor References, Paths and Addresses 20

原创
2018/12/13 15:24
阅读数 125

原文:https://doc.akka.io/docs/akka/2.5/general/addressing.html

在这里描述了如何在可能分布的actor系统中识别和定位actor。它与Actor系统形成内在监督层次结构以及Actor之间的通信相对于它们在多个网络节点上的放置是透明的中心思想联系在一起。

上图显示了Actor系统中最重要的实体之间的关系,请继续阅读详细信息。

What is an Actor Reference?

actor reference是ActorRef的子类型,其最重要的目的是支持向它所代表的actor发送消息。每个Actor都可以通过self字段访问其(local)引用,包括对于发送给其他actor的所有消息。在消息处理期间,actor可以通过sender()方法访问表示当前消息的发送者的引用。

根据actor系统的配置,支持几种不同类型的actor引用:

  • 纯粹的本地actor引用由未配置为支持网络功能的actor系统使用。如果通过网络连接发送到远程JVM,这些actor引用将不起作用。
  • 启用远程处理时的本地actor引用由actor系统使用,该系统支持那些表示同一JVM中的actor的引用的网络功能。为了在发送到其他网络节点时也可以访问,这些引用包括协议和远程寻址信息。
  • 存在用于路由器的本地Actor引用的子类型(即,在路由器特征中混合的角色)。它的逻辑结构与前面提到的本地引用相同,但是向它们发送消息直接发送给它们的一个子节点。
  • 远程actor引用表示使用远程通信可访问的actor,即向它们发送消息将透明地序列化消息并将它们发送到远程JVM。
  • 有几种特殊类型的actor引用,其行为类似于本地actor引用,用于所有实际目的:
  1. PromiseActorRef是Promise的特殊表示,目的是由Actor的响应完成。akka.pattern.ask创建此actor reference。
  2. DeadLetterActorRef是dead信服务的默认实现,Akka将所有目的地关闭或不存在的消息路由到该服务。
  3. EmptyLocalActorRef是Akka在查找不存在的本地actor路径时返回的内容:它等同于DeadLetterActorRef,但它保留了它的路径,以便Akka可以通过网络发送它并将其与该路径的其他现有actor引用进行比较,其中可能是在Actor销毁前获得的。
  • 然后有一些一次性的内部实现,可能你永远不会真的可能啊到:
  1. 有一个Actor引用不代表一个Actor,但只是作为根守护者的伪监督者,我们称之为“the one who walks the bubbles of space-time”。
  2. 在实际启动actor创建工具之前启动的第一个日志记录服务是一个假的actor引用,它接受日志事件并将它们直接打印到标准输出;它是Logging.StandardOutLogger。

What is an Actor Path?

由于Actor是以严格的分层方式创建的,因此存在一个独特的Actor名称序列,通过递归地跟随子和父母之间的监督链接向下朝向Actor系统的根来给出。此序列可以看作是文件系统中的文件夹,因此我们采用名称“path”来引用它,尽管actor层次结构与文件系统层次结构有一些根本区别。

一个actor路径包含一个anchor,它标识了actor系统,然后是路径元素的串联,从根守护者到指定的actor;path元素是遍历的actor的名称,并用斜杠分隔。

What is the Difference Between Actor Reference and Path?

actor reference指定一个actor,reference的生命周期与actor的生命周期相匹配;一个actor path代表一个名字,该名字可能是也可能不是由Actor在的位置,而且path本身没有生命周期,它永远不会变得无效。您可以在不创建actor的情况下创建actor path,但是如果不创建相应的actor,则无法创建actor reference。

您可以创建一个actor,终止它,然后创建一个具有相同actor path的新actor。新创建的Actor是的新化身。这不是同一个Actor。对旧化身的Actor引用对新的化身无效。发送到旧actor 应用的消息即使具有相同的路径,也不会被传递给新的化身。

Actor Path Anchors

每个actor路径都有一个地址组件,描述了可以访问相应actor的协议和位置,然后是从根目录开始的层次结构中actor的名称。例子是:

这里,akka.tcp是2.4版本的默认远程传输;其他运输工具是可插拔的。主机和端口部分的解释(即示例中的host.example.com:5678)取决于所使用的传输机制,但它必须遵守URI结构规则。

Logical Actor Paths

通过遵循父监督链接到根监护人获得的唯一路径称为logical actor path。此路径与actor的创建祖先完全匹配,因此只要设置了actor系统的远程配置(以及路径的地址组件),它就完全确定了。

Physical Actor Paths

虽然逻辑actor路径描述了一个actor系统内的功能位置,但是基于配置的远程部署意味着可以在不同于其父节点的网络主机上创建actor,即在不同的actor系统内。在这种情况下,遵循来自根监护人的actor路径需要遍历网络,这是一项代价高昂的操作。因此,每个actor也有一个物理路径,从实际actor对象所在的actor系统的根守护者开始。在查询其他actor时使用此路径作为发送方引用将允许它们直接回复此actor,从而最大限度地减少路由引起的延迟。

一个重要方面是物理actor路径从不跨越多个actor系统或JVM。这意味着如果远程监督其祖先之一,则演员的逻辑路径(监督层级)和物理路径(演员部署)可能会发散。

How are Actor References obtained?

如何获得actor引用有:通过创建actor或查找它们,后者的功能来自于从具体actor路径创建actor引用和查询逻辑actor层次结构的两种方式。

Creating Actors

Actor系统通常是通过使用ActorSystem.actorOf方法在守护者actor下创建actor,然后在创建的actor中使用ActorContext.actorOf来生成actor树来启动的。这些方法返回对新创建的actor的引用。每个Actor都可以直接访问(通过其ActorContext)其父级,自身及其子级的引用。这些引用可以在消息中发送给其他Actor,使他们能够直接回复。

Looking up Actors by Concrete Path

 此外,可以使用ActorSystem.actorSelection方法查找actor引用。该选择可以用于与所述Actor进行通信,并且在传送每个消息时查找与该选择相对应的Actor。

要获取绑定到特定actor的生命周期的ActorRef,您需要向actor发送消息(例如内置Identify消息)并使用actor的回复的sender()引用。

Absolute vs. Relative Paths

除了ActorSystem.actorSelection之外,还有ActorContext.actorSelection,它在任何actor中都可用作context.actorSelection。这会产生一个actor selection,就像它在ActorSystem上的双胞胎一样,但不是从actor树的根开始查找路径,而是从当前的actor开始。由两个点(“..”)组成的路径元素可用于访问父actor。例如,您可以向特定的兄弟发送消息:

也可以通常的方式在上下文中查找绝对路径,即

将按预期工作。

Querying the Logical Actor Hierarchy

由于actor系统形成类似层次结构的文件系统,因此可以采用与Unix shell支持的相同方式匹配路径:您可以用通配符(*«*»*和«?»)替换(部分)路径元素名称制定一个可以匹配零个或多个实际Actor的选择。因为结果不是单个actor引用,所以它具有不同类型的ActorSelection,并且不支持ActorRef执行的完整操作集。可以使用ActorSystem.actorSelection和ActorContext.actorSelection方法制定选择,并支持发送消息:

将msg发送给包括当前Actor在内的所有兄弟姐妹。对于使用actorSelection获得的引用,完成监督层次结构的遍历以便执行消息发送。由于与消息选择匹配的确切Actor集可能会在消息进入收件人时发生变化,因此无法观看选择的生动性变化。为了做到这一点,通过发送请求并收集所有答案,提取发件人参考,然后观察所有发现的具体Actor来解决不确定性。在将来的版本中可以改进这种解决选择的方案。

Actor Reference and Path Equality

ActorRef的相等性与ActorRef对应于目标actor化身的意图相匹配。当两个actor引用具有相同的路径并指向相同的actor化身时,它们相等。指向已终止的actor的引用不会比较指向具有相同路径的另一个(重新创建的)actor的引用。请注意,由失败引起的actor的重启仍然意味着它是相同的actor化身,即对于ActorRef的使用者不可见重启。

如果您需要跟踪集合中的actor引用并且不关心确切的actor化身,则可以使用ActorPath作为键,因为在比较actor路径时不考虑目标actor的标识符。

Reusing Actor Paths

当Actor被终止时,它的引用将指向dead信邮箱,DeathWatch将发布其最后的过渡,并且通常不会再次恢复生命(因为Actor生命周期不允许这样)。虽然有可能在以后创建一个具有相同路径的actor ,由于在不保持所有可用的actor的集合可用的情况下无法强制执行相反的操作。

在非常具体的情况下做这件事可能是正确的,但要确保将这个处理精确地限制在Actor的主管,因为这是唯一可以可靠地检测到名称的正确注销的Actor,在此之前创建新的孩子会失败。 

在测试期间,当测试对象依赖于在特定路径上实例化时,也可能需要它。在这种情况下,最好模拟其主管,以便它将Terminated消息转发到测试过程中的适当点,使后者能够等待正确的名称注销。

The Interplay with Remote Deployment

当actor创建子节点时,actor系统的部署者将决定新actor是在同一个JVM中还是在另一个节点上。在第二种情况下,Actor的创建将通过网络连接触发,以在不同的JVM中发生,从而在不同的Actor系统中发生。远程系统将新actor放置在为此目的保留的特殊路径下方,新actor的主管将是远程actor引用(表示触发其创建的actor)。在这种情况下,context.parent(supervisor引用)和context.path.parent(actor的路径中的父节点)不代表同一个actor。但是,在主管中查找孩子的名字会在远程节点上找到它,保留逻辑结构,例如发送到未解析的actor引用时。

What is the Address part used for?

通过网络发送actor引用时,它由其路径表示。因此,该路径必须完全编码将消息发送给底层Actor所需的所有信息。这是通过在路径字符串的地址部分中编码协议,主机和端口来实现的。当actor系统从远程节点接收actor路径时,它会检查该路径的地址是否与该actor系统的地址匹配,在这种情况下,它将被解析为actor的本地引用。否则,它将由远程actor引用表示。

Top-Level Scopes for Actor Paths

路径层次结构的根目录是根守护者,在该守护者之上找到所有其他actor;它的名字是 ”/”。下一级包括以下内容:

  • “/ user”是所有用户创建的顶级Actor的守护者;使用ActorSystem.actorOf创建的actor位于此下方。
  • “/ system”是所有系统创建的顶级Actor的守护者,例如记录在actor系统开始时由配置自动部署的侦听器或actor。
  • “/ deadLetters”是dead letter actor,它是发送给已停止或不存在的actor的所有消息被重新路由的地方(尽力而为:即使在本地JVM中也可能丢失消息)。
  • “/ temp”是所有系统创建的临时Actor的守护者,例如:那些在ActorRef.ask的实现中使用的。
  • “/ remote”是一个人为路径,所有其主管是远程参与者的Actor都在其下面。

为这样的Actor构建命名空间的需要源于一个中心且非常简单的设计目标:层次结构中的所有东西都是Actor,所有Actor都以相同的方式运作。因此,您不仅可以查找您创建的Actor,还可以查找系统监护人并向其发送消息(在这种情况下,它将尽职尽责地丢弃)。这个强大的原则意味着没有要记住的怪癖,它使整个系统更加统一和一致。

如果您想了解有关Actor系统顶层结构的更多信息,请查看The Top-Level Supervisors

原文:https://doc.akka.io/docs/akka/2.5/general/addressing.html

未完待续!

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部