您的位置:首页 > 其它

Akka基本概念——Actor引用、路径和地址

2018-01-16 11:26 579 查看
本章描述了如何在分布式的Actor系统中识别和定位Actor。

其中涉及到Actor系统分层监督的中心思想以及Actor之间经过多网络节点的消息通信。



上图显示了Actor系统中最重要的实体之间的关系

什么是 Actor Reference (Actor引用)

actor reference是ActorRef的的子类型,ActorRef的主要作用是支持向它

所代表的Actor发送消息。

每个actor都可以通过self来访问它的规范(本地)引用,默认情况下,

此引用也被作为给其他Actor发送消息的发件人使用。

在消息处理期间,Actor可以通过访问sender字段获取消息发送方的引用。

根据actor系统的配置,有几种不同类型的actor reference:

* 纯本地actor引用(Purely local actor references)被没有配置为支持联网功能的actor系统使用。

如果通过网络连接发送到远程JVM,这些actor引用将不起作用。

开启远程之后,本地actor引用(Local actor references)由同一JVM内支持联网的actor系统使用,

为了能发送到其他网络节点,这些actor引用需要包括协议和远程寻址信息。

有一种本地actor引用的子类型是由routers(混合了Router特质的actor)使用。

其逻辑结构与上述的本地引用相同,但发送消息会直接发送给他们的子actor。

远程Ator引用(Remote actor references)可以代表远程Actor,

发送消息给他们的时候消息会被序列化并发送到远程JVM。

有一些特殊类型的Actor引用,表现上和local actor reference相似。

PromiseActorRef是Promise的特殊代表,目的是通过Actor的回应完成。

akka.pattern.ask创建这个actor引用。

DeadLetterActorRef是dead letter服务的默认实现,

Akka将所有目的地被关闭或不存在的消息发送到该服务。

EmptyLocalActorRef是Akka在查找不存在的本地actor路径时返回的内容:

它相当于一个DeadLetterActorRef,但它保留了这个路径,

以便Akka可以通过网络发送它并将它与该路径下其他已有的actor引用进行比较,

以发现存在的可能。

什么是Actor Path

由于Actor是以严格等级的方式创建的,所以存在一个由Actor姓名根据父子关系

顺序递归到root而形成的actor系统的的唯一序列。

这个序列类似与文件系统中的文件夹包含关系,

因此我们采用名称“path”来表示它。正如在一些真实的文件系统中,

Actor也有“符号链接”,即一个Actor可以使用多于一条路径到达,

即一个Actor可以通过不止一条路径来访问。

一个Actor路径由一个锚点组成,该锚点标识了Actor系统,

后面跟随者从root到指定Actor的路径元素的连接; 路径元素是遍历actor的名称,

并用斜杠分隔。

Actor Reference和Path的区别

一个Actor引用指定单独的Actor,它的生命周期和该Actor的生命周期一致;

一个Actor路径代表一个名字,这个名字可能会或不会被Actor占据,

并且路径本身是没有生命周期的,也永远不会失效。

您可以创建Actor路径而不创建Actor,但不能创建Actor引用而不创建相应的actor。

这些定义是不支持actorFor的,
这就是为什么弃用actorFor而选用actorSelection的原因之一


你可以创建一个Actor,终止它,然后用同样的actor path创建一个新的actor。

新创建的actor指定的是新的actor,和终止的不是一个。对于新的actor,

旧的actor引用是无效的,新的actor无法接收到发往旧的actor引用的消息,

即使他们有相同的路径。

Actor Path Anchors (锚)

每个actor路径都有一个地址组件,

描述相应actor可访问的协议和位置,后面跟随从层次结构root开始的actor名称,例如:

> "akka://my-sys/user/service-a/worker1"                   // purely local
> "akka.tcp://my-sys@host.example.com:5678/user/service-b" // remote
> "cluster://my-cluster/service-c"                         // clustered (Future Extension)


这里的akka.tcp是2.2版本默认的远程运输协议,可以插入别的协议,比如akka.udp

Actor的逻辑路径

由root到actor的唯一路径

Actor的物理路径

如果父Actor在不同的网络上,逻辑路径需要跨越网络而付出昂贵代价,

因此,每个Actor有一个物理路径。

如何获取Actor引用

对于如何获得Actor引用一般有两种方法:通过创建Actor或者通过查找Actor,

后者可以通过具体actor路径和actor逻辑层次来完成。

创建Actor

一个actor系统通常使用ActorSystem.actorOf方法在守护actor下

开始创建actor,然后用ActorContext.actorOf在已创建的actor下生成一个actor树。

这些方法会给新创建的actor返回一个引用。每一个actor可以直接访问

其父actor,自身和子actor(通过ActorContext)。

这些引用将用在给别的actor发送消息时能收到回复。

通过路径查找actor

另外,actor引用可以通过ActorSystem.actorSelection方法来查找。

注意:弃用actorFor而选用actorSelection的原因是,
利用前者来获取actor引用对于本地和远程的actor结果是不一样的。


绝对路径和相对路径

类似与linux路径,路径元素中包含两个点(”..”)可以用来访问父actor

相对路径  context.actorSelection("../brother") ! msg

绝对路径  context.actorSelection("/user/serviceA") ! msg


在逻辑层次结构中查询

既然actor系统是类文件系统层次结构,

通过一些linux路径通配符也是可行的:

比如可以用 “*” 来替换路径名称来表示选项,

它可以匹配0个或更多个actor。

context.actorSelection("../*") ! msg


比如这样会给当前actor自己和所有兄弟actor发消息。

总结actorOf VS actorSelection VS actorFor

* actorOf只能创建一个新的actor,当这个方法被调用的时候
(可能是任何的actor或actor system),
它会在当前context种创建一个直接子actor

* actorSelection只能在发送消息的时候查找已经存在的actor,
也就是说selection被创建时,既不能创建actor也不能验证actor的存在性。

* actorFor(已被actorSelection取代)只能查找一个已经存在的actor,
不能创建actor。


Actor Reference 和 Path Equality

当两个actor的引用有相同的路径并指向相同的actor化身的时候

它们就被认为是等价的。如果其中一个actor已经终止,则虽然路径相同则

不再等价。

注意:由于actor故障而重启的actor和之前是同一个,也就是说重启对于

ActorRef来说是透明的。

顶级actor路径的范围

在路径层次结构的根部有一个root监管者,

它用”/”来表示。下一个等级由如下列表所示组成:

“/user”是所有用户创建最高等级的守护者actor;

通过ActorSystem.actorOf来创建。

“/system”是所有系统创建最高等级的守护者actor,

例如日志监听器或者在actor系统启动时通过配置自动部署的actor。

“/deadLetters”是死信actor,所有发送给已停止的或不存在的

actor的消息都被重新路由到此处

(消息也有可能在本地JVM中丢失)。

“/temp”是所有短命的系统创建actor的守护者,

例如那些用于实现ActorRef.ask的actor。

“/remote”,其下所有actor的人工路径,这些actor的监管者都是远程actor引用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  actor akka scala