美文网首页
akka学习笔记(一)

akka学习笔记(一)

作者: 请叫我大花 | 来源:发表于2018-09-18 15:46 被阅读0次

    akka的重启过程中所发生事件的精确次序

    1. actor被挂起(意味着它不会处理正常消息直到被恢复),并递归挂起其所有子actor

    2. 调用旧实例的 preRestart hook (缺省实现是向所有子actor发送终止请求并调 用 postStop)

    3. 等待所有子actor终止(使用context.stop())直到 preRestart 最终结束;这里所有的 actor操作都是非阻塞的,最后被杀掉的子actor的终止通知会影响下一步的执行

    4. 再次调用原来提供的工厂生成actor的新实例

    5. 调用新实例的postRestart方法(其默认实现是调用preStart方法)

    6. 对步骤3中没有被杀死的所有子actor发送重启请求;重启的actor会遵循相同的过程,从 步骤2开始

    7. 恢复这个actor

    Actor引用,路径和地址

    引用

     Actor引用是 ActorRef 的子类,其最重要的目的是支持向它所代表的actor发送消息。每个

    actor通过self字段来访问自己的标准(本地)引用;在给其它actor发送的消息中也缺省包

    含这个引用。反过来,在消息处理过程中,actor可以通过sender()方法来访问到当前消息的

    发送者的引用。

    actor的引用类型:

    纯本地actor引用,在配置为不使用网络功能的actor系统中使用,这些actor引用如果通过网络连接传给远程JVM,将不能正常工作

    本地actor引用,在配置为使用远程功能的actor系统中使用,来代表同一个JVM的

    actor。为了能够在被发送到其它节点时仍然可达,这些引用包含了协议和远程地址信 息。

    本地actor引用的一个子类,用在路由器中(routers,即混入 了 Router trait的actor)。

    它的逻辑结构与之前的本地引用是一样的,但是向它们发送的消息会被直接重定向到它

    的子actor。

    远程actor引用,代表可以通过远程通讯访问的actor,即向他们发送消息时会透明地对

    消息进行序列化,并发送到别的JVM。

    有几种特殊的actor引用类型,在实际用途中比较类似本地actor引用:

    PromiseActorRef 表示一个Promise,其目的是通过一个actor返回的响应来完成。它

    是由 akka.pattern.ask 创建的。

    DeadLetterActorRef是死信服务的缺省实现,所有接收方被关闭或不存在的消息都

    被重新路由在此。

    EmptyLocalActorRef是当查找一个不存在的本地actor路径时Akka返回的:它相当于

    DeadLetterActorRef,但是它保有其路径因此可以在网络上发送,并与其它相同路

    径的存活的actor引用进行比较,其中一些存活的actor引用可能在该actor消失之前

    被得到。

    然后有一些内部实现,你应该永远不会用上:

    有一个actor引用并不表示任何actor,只是作为根actor的伪监管者存在,我们称它

    为“时空气泡穿梭者”。

    在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引用的消息不会被传递到新的化身,即使它们拥有相同的路径。

    "akka://my‐sys/user/service‐a/worker1" // 纯本地

    "akka.tcp://my‐sys@host.example.com:5678/user/service‐b" // 远程

    Actor逻辑路径

    顺着actor的父监管链一直到根的唯一路径被称为actor逻辑路径。这个路径与actor的创建祖

    先关系完全吻合,所以当actor系统的远程调用配置(和配置中路径的地址部分)设置好后

    它就是完全确定的了

    Actor物理路径

    Actor逻辑路径描述它在一个actor系统内部的功能位置,而基于配置的远程部署意味着一个

    actor可能在另外一台网络主机上被创建,即另一个actor系统中。在这种情况下,从根守护

    者穿过actor路径来找到该actor肯定需要访问网络,这是一个很昂贵的操作。因此,每一个

    actor同时还有一条物理路径,从actor对象实际所在的actor系统的根开始。与其它actor通信

    时使用物理路径作为发送方引用,能够让接收方直接回复到这个actor上,将路由延迟降到

    最小。

    物理路径的一个重要性质是它决不会跨多个actor系统或跨JVM虚拟机。这意味着如果一个

    actor有祖先被远程监管,则其逻辑路径(监管树)和物理路径(actor部署)可能会分叉

    Actor引用和路径相等性

    ActorRef的相等性与ActorRef的目的匹配,即一个ActorRef对应一个目标actor化身。两个

    actor引用进行比较时,如果它们有相同的路径且指向同一个actor化身,则两者相等。指向

    一个已终止的actor的引用,与指向具有相同路径但却是另一个(重新创建)actor的引用是

    不相等的。需要注意的是,由于失败造导致的actor重启,仍意味着它是同一个actor化身,

    即重新启动对ActorRef消费者是不可见的。

    与远程部署之间的互操作

    当一个actor创建一个子actor,actor系统的部署者会决定新的actor是在同一个jvm中还是在

    其它节点上。如果是后者,actor的创建会通过网络连接引到另一个jvm中进行,因而在另一

    个actor系统中。远程系统会将新的actor放在一个专为这种场景所保留的特殊路径下,新的

    actor的监管者将会是一个远程actor引用(代表触发它创建动作的actor)。这

    时,context.parent(监管者引用)和context.path.parent(actor路径上的父actor)表示的

    actor是不同的。然而,在其监管者中查找这个actor的名称将会在远程节点上找到它,保持

    其逻辑结构,例如向另一个未确定(unresolved)的actor引用发送消息。

    Actor路径的顶级作用域

    在路径树的根上是根监管者,所有其他actor都可以从通过它找到;它的名字是"/"。在第二

    个层次上是以下这些:

    "/user" 是所有由用户创建的顶级actor的监管者;用 ActorSystem.actorOf创建的actor在

    其下。

    "/system" 是所有由系统创建的顶级actor的监管者,如日志监听器,或由配置指定在

    actor系统启动时自动部署的actor。

    "/deadLetters" 是死信actor,所有发往已经终止或不存在的actor的消息会被重定向到

    这里(以尽最大努力为基础:即使在本地JVM,消息也可能丢失)

    "/temp"是所有系统创建的短时actor的监管者,例如那些在ActorRef.ask的实现中用到的

    actor。

    "/remote" 是一个人造虚拟路径,用来存放所有其监管者是远程actor引用的actor。

    失败消息的传达

    请注意,上面只讨论了actor之间的用户消息的顺序保证。一个actor的孩子的失败是通过特

    殊的系统消息传达的,与普通用户发送的消息没有顺序关系。特别是:

    子 actor C 发送 M 给其父节点 P

    子 actor 失败并发送失败消息 F

    父 actor P 可能以M, F或F, M的顺序收到两个事件

    这样做的原因是,内部系统消息有其自己的邮箱,因此用户和系统信息的排队的顺序不能保

    证其出队的时间顺序

    配置

    日志级别和后端记录器

    启用远程

    消息序列化

    路由器定义

    调度的调整

    配置读取的地方

    Akka的所有配置都保存在ActorSystem的实例中,或者换一种说法,从外界来

    看,ActorSystem是配置信息的唯一消费者。在构造一个actor系统时,你可以选择传进一

    个Config对象,如果不传则等效于传入ConfigFactory.load()(通过正确的类加载器)。粗略

    的讲,这意味着默认会解析classpath根目录下所有的application.conf,application.json和

    application.properties文件——请参考前面提到的文档以获取细节。然后actor系统会合并

    classpath根目录下的所有 reference.conf行成后备配置,也就是说,它在内部使用

    appConfig.withFallback(ConfigFactory.defaultReference(classLoader))

    相关文章

      网友评论

          本文标题:akka学习笔记(一)

          本文链接:https://www.haomeiwen.com/subject/ozkpnftx.html