原文:https://doc.akka.io/docs/akka/2.5/general/addressing.htmlhtml
在这里描述了如何在可能分布的actor系统中识别和定位actor。它与Actor系统造成内在监督层次结构以及Actor之间的通讯相对于它们在多个网络节点上的放置是透明的中心思想联系在一块儿。shell
上图显示了Actor系统中最重要的实体之间的关系,请继续阅读详细信息。网络
actor reference是ActorRef的子类型,其最重要的目的是支持向它所表明的actor发送消息。每一个Actor均可以经过self字段访问其(local)引用,包括对于发送给其余actor的全部消息。在消息处理期间,actor能够经过sender()方法访问表示当前消息的发送者的引用。tcp
根据actor系统的配置,支持几种不一样类型的actor引用:工具
因为Actor是以严格的分层方式建立的,所以存在一个独特的Actor名称序列,经过递归地跟随子和父母之间的监督连接向下朝向Actor系统的根来给出。此序列能够看做是文件系统中的文件夹,所以咱们采用名称“path”来引用它,尽管actor层次结构与文件系统层次结构有一些根本区别。测试
一个actor路径包含一个anchor,它标识了actor系统,而后是路径元素的串联,从根守护者到指定的actor;path元素是遍历的actor的名称,并用斜杠分隔。编码
actor reference指定一个actor,reference的生命周期与actor的生命周期相匹配;一个actor path表明一个名字,该名字多是也可能不是由Actor在的位置,并且path自己没有生命周期,它永远不会变得无效。您能够在不建立actor的状况下建立actor path,可是若是不建立相应的actor,则没法建立actor reference。spa
您能够建立一个actor,终止它,而后建立一个具备相同actor path的新actor。新建立的Actor是的新化身。这不是同一个Actor。对旧化身的Actor引用对新的化身无效。发送到旧actor 应用的消息即便具备相同的路径,也不会被传递给新的化身。设计
每一个actor路径都有一个地址组件,描述了能够访问相应actor的协议和位置,而后是从根目录开始的层次结构中actor的名称。例子是:3d
这里,akka.tcp是2.4版本的默认远程传输;其余运输工具是可插拔的。主机和端口部分的解释(即示例中的host.example.com:5678)取决于所使用的传输机制,但它必须遵照URI结构规则。
经过遵循父监督连接到根监护人得到的惟一路径称为logical actor path。此路径与actor的建立祖先彻底匹配,所以只要设置了actor系统的远程配置(以及路径的地址组件),它就彻底肯定了。
虽然逻辑actor路径描述了一个actor系统内的功能位置,可是基于配置的远程部署意味着能够在不一样于其父节点的网络主机上建立actor,即在不一样的actor系统内。在这种状况下,遵循来自根监护人的actor路径须要遍历网络,这是一项代价高昂的操做。所以,每一个actor也有一个物理路径,从实际actor对象所在的actor系统的根守护者开始。在查询其余actor时使用此路径做为发送方引用将容许它们直接回复此actor,从而最大限度地减小路由引发的延迟。
一个重要方面是物理actor路径从不跨越多个actor系统或JVM。这意味着若是远程监督其祖先之一,则演员的逻辑路径(监督层级)和物理路径(演员部署)可能会发散。
如何得到actor引用有:经过建立actor或查找它们,后者的功能来自于从具体actor路径建立actor引用和查询逻辑actor层次结构的两种方式。
Actor系统一般是经过使用ActorSystem.actorOf方法在守护者actor下建立actor,而后在建立的actor中使用ActorContext.actorOf来生成actor树来启动的。这些方法返回对新建立的actor的引用。每一个Actor均可以直接访问(经过其ActorContext)其父级,自身及其子级的引用。这些引用能够在消息中发送给其余Actor,使他们可以直接回复。
此外,可使用ActorSystem.actorSelection方法查找actor引用。该选择能够用于与所述Actor进行通讯,而且在传送每一个消息时查找与该选择相对应的Actor。
要获取绑定到特定actor的生命周期的ActorRef,您须要向actor发送消息(例如内置Identify消息)并使用actor的回复的sender()引用。
除了ActorSystem.actorSelection以外,还有ActorContext.actorSelection,它在任何actor中均可用做context.actorSelection。这会产生一个actor selection,就像它在ActorSystem上的双胞胎同样,但不是从actor树的根开始查找路径,而是从当前的actor开始。由两个点(“..”)组成的路径元素可用于访问父actor。例如,您能够向特定的兄弟发送消息:
也能够一般的方式在上下文中查找绝对路径,即
将按预期工做。
因为actor系统造成相似层次结构的文件系统,所以能够采用与Unix shell支持的相同方式匹配路径:您能够用通配符(*«*»*和«?»)替换(部分)路径元素名称制定一个能够匹配零个或多个实际Actor的选择。由于结果不是单个actor引用,因此它具备不一样类型的ActorSelection,而且不支持ActorRef执行的完整操做集。可使用ActorSystem.actorSelection和ActorContext.actorSelection方法制定选择,并支持发送消息:
将msg发送给包括当前Actor在内的全部兄弟姐妹。对于使用actorSelection得到的引用,完成监督层次结构的遍历以便执行消息发送。因为与消息选择匹配的确切Actor集可能会在消息进入收件人时发生变化,所以没法观看选择的生动性变化。为了作到这一点,经过发送请求并收集全部答案,提取发件人参考,而后观察全部发现的具体Actor来解决不肯定性。在未来的版本中能够改进这种解决选择的方案。
ActorRef的相等性与ActorRef对应于目标actor化身的意图相匹配。当两个actor引用具备相同的路径并指向相同的actor化身时,它们相等。指向已终止的actor的引用不会比较指向具备相同路径的另外一个(从新建立的)actor的引用。请注意,由失败引发的actor的重启仍然意味着它是相同的actor化身,即对于ActorRef的使用者不可见重启。
若是您须要跟踪集合中的actor引用而且不关心确切的actor化身,则可使用ActorPath做为键,由于在比较actor路径时不考虑目标actor的标识符。
当Actor被终止时,它的引用将指向dead信邮箱,DeathWatch将发布其最后的过渡,而且一般不会再次恢复生命(由于Actor生命周期不容许这样)。虽然有可能在之后建立一个具备相同路径的actor ,因为在不保持全部可用的actor的集合可用的状况下没法强制执行相反的操做。
在很是具体的状况下作这件事多是正确的,但要确保将这个处理精确地限制在Actor的主管,由于这是惟一能够可靠地检测到名称的正确注销的Actor,在此以前建立新的孩子会失败。
在测试期间,当测试对象依赖于在特定路径上实例化时,也可能须要它。在这种状况下,最好模拟其主管,以便它将Terminated消息转发到测试过程当中的适当点,使后者可以等待正确的名称注销。
当actor建立子节点时,actor系统的部署者将决定新actor是在同一个JVM中仍是在另外一个节点上。在第二种状况下,Actor的建立将经过网络链接触发,以在不一样的JVM中发生,从而在不一样的Actor系统中发生。远程系统将新actor放置在为此目的保留的特殊路径下方,新actor的主管将是远程actor引用(表示触发其建立的actor)。在这种状况下,context.parent(supervisor引用)和context.path.parent(actor的路径中的父节点)不表明同一个actor。可是,在主管中查找孩子的名字会在远程节点上找到它,保留逻辑结构,例如发送到未解析的actor引用时。
经过网络发送actor引用时,它由其路径表示。所以,该路径必须彻底编码将消息发送给底层Actor所需的全部信息。这是经过在路径字符串的地址部分中编码协议,主机和端口来实现的。当actor系统从远程节点接收actor路径时,它会检查该路径的地址是否与该actor系统的地址匹配,在这种状况下,它将被解析为actor的本地引用。不然,它将由远程actor引用表示。
路径层次结构的根目录是根守护者,在该守护者之上找到全部其余actor;它的名字是 ”/”。下一级包括如下内容:
为这样的Actor构建命名空间的须要源于一个中心且很是简单的设计目标:层次结构中的全部东西都是Actor,全部Actor都以相同的方式运做。所以,您不只能够查找您建立的Actor,还能够查找系统监护人并向其发送消息(在这种状况下,它将尽职尽责地丢弃)。这个强大的原则意味着没有要记住的怪癖,它使整个系统更加统一和一致。
若是您想了解有关Actor系统顶层结构的更多信息,请查看The Top-Level Supervisors。
原文:https://doc.akka.io/docs/akka/2.5/general/addressing.html
未完待续!