这章主要介绍在分布式akka系统中actor是如何识别和寻址的。它的主要思想是actor系统本身形成的内在监护层级结构以及跨多个网络节点中actor之间的通信是位置透明的。
上面这张图描述了akka系统中主要的几种实体之间的关系,下面将对这张关系图做详细介绍。
actor引用
actor引用是actorRef的子类,它最重要的作用就是支持发生消息给它所代表的actor对象。actor对象可以通过self属性访问它自己的actor引用。如果使用actor发送消息,那么发送的消息中也默认包含了这个actor引用;如果actor是处理消息,那么这个actor可以通过sender属性来获取发送actor的actor引用。
根据配置的不同,actor系统可以支持下面几种不同类型的actor引用:
1.如果actor系统的配置不支持网络功能,那么只能支持纯本地actor引用,通过网络连接到远程jvm将不起作用。
2.如果actor系统的配置支持网络功能,那么本地引用将代表该jvm中的actor对象实现网络功能,为了使得这些引用发送到远程节点之后,还能被远程节点访问,这些引用包含了协议信息和地址信息。
3.还有一种本地actor引用的子类,它包含了路由信息,被用来实现路由功能。它的逻辑结构与上面说的本地actor引用是一样的,不同的是通过路由引用发送消息之后,路由引用会直接分配消息给它代表的那些子actor。
4.如果需要通过网络访问远程actor,那么通过远程actor引用能够访问到actor。通过远程actor引用发送消息,它会先将消息序列化,然后将消息发送给远程jvm。
5.为特殊场景设计的几种特殊actor引用,这些actor引用与本地actor引用的行为是类似的。
a.Promise actor的引用PromiseActorRef,表示一个actor完成响应完成之后的promise,akka.pattern.ask创建这个actor引用。
DeadLetterActorRef,但是它仍保证了actor的路径,以便系统能把它发送到网上,并且可以把它与系统上存在的其他actor比较路径,因为有些系统可能在它死之前被其他actor持有了。
6.某些你看不见的内部实现的一次性actor引用。
a.仅仅作为跟守护者actor的伪监护者,它不代表一个真正的actor。
b.在真正启动actor创建模块之前就启动了的日志服务系统,其实也是个伪actor引用。它接收日志事件,并且直接打印到标准输出上,即Logging.StandardOutLogger。
actor路径
因为actor的创建是在严格的层次体系系统中,沿着子actor到父actor的监管链一直到actor系统的根存在一条唯一的actor序列串,也就是actor的名字。这个序列串可以被视为文件系统中的封闭文件夹,所以用路径这个词来表示它,在一些真正的文件系统中,也叫做符号链接,比如一个actor对象能够通过多条路径被访问,除了原始路径外,其它的路径都包含到actor实际的监管祖先链的转换方法。这些特性将在下面的内容中介绍。
一个actor路径包含一个actor系统的锚,锚后面跟着具体的从根守护者到目标actor的路径元素。这些路径元素是经过的actor的名字,他们之间用斜杠隔开。
actor引用与actor路径的区别
一个actor引用表示单个的actor对象,并且actor引用的生命周期与actor对象的生命周期是一样的。而actor路径只是代表了一个actor的位置,这个位置上有可能有actor对象,也可能没有,并且路径本身是没有生周期的,是不会失效的。你可以创建一个actor路径而不创建这个actor对象,但是你不能不创建actor对象而只创建actor引用。注意:这个定义不适用于actorFor方法,这也是为什么要用actorSelection替代actorFor的原因。
你可以创建一个actor并终止它,然后在同样的路径下创建洗个新的actor,新创建的actor对象是actor类的新对象,与老的actor对象不是同一个对象。老的actor对象的引用不是新对象的引用。发送给老的actor引用的消息不会发送给新actor对象,即使他们拥有相同的路径。
actor路径锚
每一个actor路径都有一个地址组件,用来描述相应的actor对象的协议和位置,地址组件后面跟着从根守护开始的层级actor名字。下面是一个例子:
1、 纯本地地址:"akka://my-sys/user/ervice-a/worker1"
2、远程访问路径:"akka.tcp://my-sys@host.example.com:8080/user/service-b"
在第二个中,akka.tcp是akka 2.2版中默认的传输协议。其他的传输协议是可插拔的,比如使用UDP访问远程主机可以使用akka.udp。主机和端口号(host.example.com:8080)的解析依赖于具体的传输机制,但是必须遵循URI结构规则。
逻辑actor路径
从根守护者一直链接到某个actor的父监护者的唯一路径,称为逻辑actor路径。这条路径精确配到actor的所有祖先创建。因此,一旦actor系统配置和地址组件设置好之后,那么每个actor的路径也就确定好了。
物理actor路径
逻辑actor路径描述的是一个actor系统的功能路径,基于配置的远程依赖意味着一个actor可以与它的父actor处于不同的actor系统和网络节点上。在这种场景下,从根守护者沿着actor路径追溯网络地址,是比较费力的操作。因此,每一个actor还有一个物理路径,物理路径的起点就是这个actor所在的actor系统的根守护。
当请求其他actor时,使用物理路径作为发送引用会使得目标actor的直接作出响应,并最小化了路由的延迟。
一个需要特别注意的是物理逻辑绝不会跨越多个actor系统和jvm,这意味着一个被远程监护的actor对象的逻辑逻辑(监护层次)和物理路径(actor依赖)可能会不一致。
如何获得actor引用
获得actor引用大致有两种:创建actor对象和查找。查找的实现又可以分为2种:通过具体的actor路径创建actor对象和请求逻辑actor层次结构。
创建actor对象
一般一个actor系统最开始的行为是用ActorSystem.actorOf或者ActorContext.actorOf(对于已存在的actor系统来扩展actor树)方法在根守护的下面创建actor对象。这些方法返回新创建actor对象的引用。actor的父actor,它自己已经他的子actor可以直接访问它的引用(通过ActorContext)。这些引用可以包含在消息中被发送出去,使得他们能直接响应。
根据具体路径查找
也可以使用ActorSystem.actorSelection方法来查找actor引用。这种方式主要用在actor通信中一个actor查询另外一个actor的引用来发送消息。
为了获得与某个特殊actor对象生命周期相关联的ActorRef ,你需要发送消息诸如内建的身份消息给这个actor,这个actor回复的sender()的返回值就是它的引用。
注意:推荐使用actorSelection 而不使用actorFor的原因是,对于本地actor和远程actor,actorFor的行为不一致。在被动actor引用中,这个actor在查找前必须存在,否则将返回一个EmptyLocalActorRef引用,即使在返回值之后这个actor被创建了。而在远程场景中,给通过actorFor获得的actor引用发送消息,没次发送消息都会悄悄地通过远程actor系统的路径查找这个actor。
绝对路劲VS相对路径
除了ActorSystem.actorSelection方法,还有ActorContext.actorSelection方法。两种不同的是,前者的路径必须是从根守护开始到目标actor。而后者可以从当前actor开始的路径,路径元素用“..”来访问父actor。你可以通过下面两种方式来给兄弟姐妹发送消息:
1.相对路径:context.actorSelection("../brother")!msg
2.绝对路径:context.actorSelection("/user/serviceA")!msg
请求逻辑actor层次
actor系统的层级结构像文件系统一样,因此像使用支持unix shells的方式一样去匹配路径是可能的:你可以使用通配符替代路径元素来匹配多个实际actor。因为这种结果可能不是单个actor引用,所以返回值是不同类型的ActorSelection,也不支持像操作单个actorRef一样来操作一个集合。使用ActorSystem.actorSelection和ActorContext.actorSelection方法并用通配符匹配出来的actor引用,可以是下面方式发生消息:context.actorSelection("../*") ! msg。这行代码将向所有的兄弟姐妹,包括自己发生消息。而通过actorFor方法获得actor引用,为了发送所有而定消息,需要访问整个监护层级。通过模糊匹配找出来的actor集合可能发生改变,即使消息正在给接收者的路上,而监控所有匹配上的actor的变化情况是不可能的。为了解决发生请求和接收响应的不确定性,先要把发送者引用提取出来,然后监控所有的接收actor。这个问题可能在后面的akka版本中解决掉。
总结actorOf vs actorSelection vs actorFor
1.actorOf仅用来创建一个新的actor对象,新创建的actor对象是actorOf所在的context(可能是任何一个actor或者actor系统)的直接子actor。
2.actorSelection仅仅是用来在发送消息时查找已经存在的actor,他不创建actor,也不会再actor创建之后去检查它的存在性。
3.actorFor(被actorSelection)取代,仅仅是查找已存在的actor。
actor引用和actor路径的相等性
actor引用的相等性是指指向同一个actor对象的引用。如果两个actor引用有相同的路径,并且指向同一个actor对象,那么认为这两个actor引用是相等的。指向一个终止的actor对象不等于另一个指向拥有相同路径的actor对象(重新创建的)。但是由于错误重启的actor意味着它还是原来的actor对象,因此actor的重启对了持有它的actor来说是透明的。
通过actorFor获取的远程actor引用没有包含识别一个actor身份的完整信息,所有这类引用不等于通过actorOf,sender或context.self获取的引用。
如果你想再集合中跟踪actor引用而不关心actor对象本身,那么可以使用ActorPath作为key。因为在比较actor路径的时候,actor对象本身是不考虑在内的。
复用actor路径
当一个actor对象终止了,它的引用将指向死信邮箱,死亡监控将发布它的变化,并且一般来说也不会希望它死而复生(因为actor的生命周期不允许它重生)。但是随后可能会在相同路径下创建一个新的actor,不过这并不是一个很好的实践:通过actorFor获取的actor引用突然在死亡之后又重新开始工作了,并且这个转变与任何其他的事件没有任何的顺序保证,因此原来的actor拒绝的消息又开始重新被新的actor接收了。
复用actor路径在非常特殊的环境中这样做可能是对的,但是必须确保只有于这个actor的监护者才有权做这种处理。因为只有它的监护者才能可靠的保证在新的actor创建之前,旧的actor名字从系统中注销了。
当测试项依赖于特殊路径的实例时,也可能需要复用actor路径。在这种场景下,最好mock它的监护者,以便在测试过程中随时发送终止消息,并能在后面等待合适的名字注销。
与远程部署的互操作
当一个actor创建了一个子actor,actor系统的部署者将决定新的actor对象是在同一个jvm中还是在另一个节点上。如果是在其他节点上,actor对象是由网络链接触发两一个jvm或actor系统来创建的。远程系统将会把该actor对象放置在专门为远程创建actor而保留的特殊路径上,它的监护者是触发创建这个actor的那个远程actor。在这种场景下,context.parent(监护者引用)和context.path.parent(在actor路径中的父节点)代表不同的actor对象。但是,通过监护者寻找子actor名字时将会在远程节点找到它,而且这个名字仍然保持着它的逻辑结构名,比如向另一个未确定的actor发送消息时。
地址端口的用途
当通过网络来发送一个actor引用时,用actor的路径来表示actor引用。因此路径中的地址字符串必须包含协议信息,host地址,端口号等所有必要的信息才能正确发送消息给潜在的actor。当actor系统接收到一个来自远程节点的actor路径时,它首先要检查这个路径的地址是否与自己匹配,地址匹配通过后才将这条路径转换为本地引用,否则认为它是一个远程actor引用。
actor路径的顶层作用域
在actor路径的层级结构的根部,存放的是根守护actor,通过它可以找到所有的actor。根路径的名字是一个斜杠“/”,后面跟着下面几种层级。
1.“/user”。所有用户创建的第一级actor的根守护actor。通过ActorSystem.actorOf创建的actor都能在“/user”下面。
2.“/system”。所有系统创建的第一级actor的根守护actor。比如日志监听actor和系统启动时读取配置创建的actor。
3.“/deadLetters”。所有发送给已终止或不存在的actor的信息都会重新路由到死信actor(即使在同一个jvm中,信息还是可能丢失)。“/deadLetters”是死信actor的根守护actor。
4.“/temp”。系统创建的生命周期短的actor的根守护。比如ActorRef.ask的实现中有用到。
5."/remote"。这是一个虚假的路径,所有监护者是远程actor引用的actor都在这个路径下存放。
上面这套构造actor的命名空间的需求源于一个非常简单集中的目的:系统层级中的每个actor都是一个actor,并且所有的actor都以同样的方式工作。因此,你不仅仅只需要查找你自己创建的actor,你还可能查找系统守护者并向它发送消息(虽然它会把你的消息丢掉)。什么是最有力的原则?最有力的原则就是它使整个系统统一和一致,没有乱七八糟的例外情况需要记忆。
相关推荐
在Java项目中,可以通过在类路径中包含这个JAR文件,导入必要的依赖,以便使用Akka Actor的功能。对于Maven或Gradle用户,可以在配置文件中添加对应的依赖项,以自动管理jar包的下载和引用。 Akka Actor的设计理念...
- actor引用、路径和地址用于在分布式系统中定位和管理actors。 - 监督和监控机制用于管理actor系统的稳定性和鲁棒性。 3. 高级特性: - 消息传递可靠性,保证消息能够被准确地发送和接收。 - 位置透明性,这...
- 解释了Actor模型、Actor系统、以及Actor引用、路径和地址的概念。 - 讲述了Akka和Java内存模型的关系,以及消息传递的可靠性。 - 介绍了Akka的监督、监控、故障容错、类型化Actor、调度器、消息箱、路由、有限状态...
Actor引用是发送消息给特定Actor的手段。 5. **生命周期管理**:Actor有自己的生命周期,包括创建、正常工作、停止等阶段。可以通过`become`和`unbecome`方法动态改变Actor的行为。 6. **故障恢复**:Akka提供了...
**Actor引用、路径和地址** Actor引用是用来与Actor通信的地址,Actor路径提供了一个唯一的标识符来引用系统内的Actor。地址则定义了Actor引用在分布式系统中的位置。 **消息传递可靠性** 在分布式系统中,消息...
每个 Actor 都有一个唯一的路径(path),可以使用 Actor 引用来发送消息。 ##### 2.4 Supervision and Monitoring 监督是 Akka 中用于处理 Actor 故障的核心机制。Akka 支持多种监督策略,例如重启(Restart)、...
Actor 引用是用来标识 Actor 的唯一标识符,而 Actor 的路径和地址则是用来定位 Actor 的具体位置。本节详细阐述了 Actor 引用的作用、路径和地址的格式以及如何使用它们进行跨进程通信。 ##### 2.6 位置透明性 ...
每个Actor都有一个唯一的路径(Path)和地址(Address),用于标识其在网络中的位置。 - **Supervision and Monitoring**:为了确保系统的稳定性和容错性,Akka提供了监督(Supervision)机制,使得父Actor可以监控...
文档会解释什么是actor,以及actor引用、路径和地址的概念。由于Akka是基于Java平台构建的,因此文档还将讨论Akka如何处理Java内存模型和消息传递保证。 在 Actors 章节中,文档将深入探讨Akka中的Actors和...
5. **Actor路径**:每个Actor都有一个唯一的路径,可以用来引用或发送消息给它。路径通常看起来像`/user/myActor`,其中`/user`是顶级命名空间,`myActor`是Actor的名字。 6. **Supervision和故障处理**:Akka支持...
- **Actor引用、路径与地址**:Actor通过其引用进行通信,而引用包含了Actor的路径和地址信息。 - **位置透明性**:Akka的一个关键特性是它的位置透明性,这意味着可以在不同的节点之间透明地移动Actor,而不改变其...
**2.5 Actor 引用、路径与地址** - **Actor 引用:** 用于向 Actor 发送消息的对象。 - **Actor 路径:** 描述 Actor 在 Actor 系统中的位置。 - **Actor 地址:** 表示 Actor 所在的物理位置,用于跨 Actor 系统的...
Actor Systems 是 Akka 中的核心组件之一,负责创建和监督 Actor。一个 Actor System 可以包含多个 Actor,并且可以嵌套其他 Actor Systems。 ##### 2.3 什么是 Actor? Actor 是 Akka 中的最小执行单元。每个 ...
**2.4 Actor 引用、路径和地址** 为了使 Actor 能够相互通信,Akka 引入了 Actor 引用的概念。每个 Actor 都有一个唯一的引用,用于发送消息。Actor 之间还可以通过路径和地址来定位彼此。 **2.5 位置透明性** ...
##### 2.4 Actor引用、路径和地址 Actor引用是Actor的代理对象,用于向Actor发送消息。每个Actor都有一个唯一的路径,这个路径由Actor的名称和所在Actor System的名称组成。通过Actor路径,可以唯一标识一个Actor。...
2.4演员引用、路径和地址(Actor References, Paths, and Addresses) 在Akka中,演员被引用通过路径和地址定位。路径类似于URL,用于标识演员系统的层级结构,而地址则关联到网络位置。 2.7Akka与Java内存模型...
- **编写代码**:从简单的 Actor 开始,逐步学习 Akka 的核心概念和技术。 ##### 1.4 必不可少的 HelloWorld 示例 - **创建 Actor**:定义一个 Actor 类继承自 `Actor`。 - **发送消息**:使用 `tell` 方法向 Actor...
总之,"akka-http-1.0-RC2.jar.zip"是一个包含了构建和运行高性能HTTP服务所需的关键组件的压缩包,它是基于Akka框架的,具有响应式、流式处理、路由定义和Actor系统集成等优势,是开发现代Web应用程序的有力工具。
##### 2.4 Actor引用、路径和地址 - **Actor References**:Actor之间的唯一标识符,用于发送消息。 - **Paths**:Actor在Actor System中的完整路径,包括Actor的名字和父Actor的信息。 - **Addresses**:表示Actor...
Actor引用,路径与地址 位置透明性 Akka与Java内存模型 消息传递可靠性 配置 Actors Actors Akka类型 容错 调度器 邮箱 路由 有限状态机(FSM) 持久化 测试Actor系统 Actor DSL 类型Actors Futures...