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

本章描述了如何在分布式的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引用。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值