文档章节

Akka消息传送可靠性 23

woshixin
 woshixin
发布于 01/18 20:38
字数 3239
阅读 15
收藏 0

原文:https://doc.akka.io/docs/akka/2.5/general/message-delivery-reliability.html

Akka可帮助您构建可靠的应用程序,这些应用程序在一台计算机中使用多个处理器核心或分布在计算机网络中。使这项工作的关键抽象是你的代码单元 -Actors之间的所有交互都是通过消息传递发生的,这就是为什么消息如何在actor之间传递的精确语义值得讲的章节。

为了给下面的讨论提供一些上下文,请考虑跨越多个网络主机的应用程序。无论是发送到本地JVM上的actor还是远程actor,通信的基本机制都是相同的,但是在传递延迟方面会有明显的差异(可能还取决于网络链路的带宽和消息大小)和可靠性。如果发送远程消息,则涉及更多步骤,这意味着更多可能出错。另一个方面是本地发送将传递对同一JVM内的消息的引用,而不对发送的基础对象进行任何限制,而远程传输将对消息大小设置限制。

编写你的Actor使得每次互动都可能是遥远的是安全的。这意味着只依赖于那些始终保证的属性,这些属性将在下面详细讨论。这在actor的实现中有一些开销。如果您愿意牺牲完整的位置透明度 - 例如在一组密切合作的Actors的情况下 - 您可以将它们始终放在同一个JVM上,并在邮件传递上享受更严格的保证。下面将进一步讨论这种权衡的细节。

作为补充部分,我们提供了一些指导,说明如何在内置的可靠性之上构建更强的可靠性。本章最后讨论了“Dead Letter Office”的作用。

一般规则

这些是消息发送的规则(即tell或!方法,它也是ask模式的基础):

  • at-most-once delivery
  • message ordering per sender–receiver pair

第一个规则通常也可以在其他actor实现中找到,而第二个规则特定于Akka。

讨论:“at-most-once”是什么意思?

在描述传递机制的语义时,有三个基本类别:

  • at-most-once:传递意味着对于传递给机制的每条消息,该消息一次传递或根本不传递;从更随意的角度来看,这意味着消息可能会丢失。

  • at-least-once:传递意味着对于传递给该机制的每个消息,可能在传递它时进行多次尝试,使得至少一个成功;再次,从更随意的角度来看,这意味着消息可能会重复但不会丢失。

  • exactly-once:交付意味着对于递交给机制的每个消息,只有一个交付给接收者;消息既不会丢失也不会重复。

第一个是最便宜的最高性能,最少的实现开销 - 因为它可以以一种即发即忘的方式完成,而不会在发送端或传输机制中保持状态。第二个需要重试以对抗传输损耗,这意味着将状态保持在发送端并且在接收端具有确认机制。第三个是最昂贵的 - 并且因此具有最差的性能 - 因为除了第二个之外它还需要将状态保持在接收端以便过滤掉重复的交付。

讨论:为什么没有保证传递?

问题的核心在于这个保证究竟意味着什么:

  1. 消息是在网络上发出的?
  2. 该消息是由其他主机收到的?
  3. 消息被放入目标actor的邮箱?
  4. 消息开始由目标actor处理?
  5. 目标actor是否成功处理了该消息?

其中每一个都有不同的挑战和成本,很明显,在任何情况下,任何消息传递库都无法遵守。

沿着同样的路线,无人需要可靠消息的推理。发送者知道交互是否成功的唯一有意义的方式是接收业务级别的确认消息,这不是Akka可以自己构成的。

Akka采用分布式计算,并通过消息传递使通信的可靠性显而易见,因此它不会试图欺骗和模拟漏洞抽象。这是一个在Erlang中取得巨大成功的模型,需要用户围绕它设计应用程序。您可以在Erlang文档(第10.9节和第10.10节)中阅读有关此方法的更多信息,Akka会密切关注它。

在这个问题上的另一个角度是,通过仅提供基本保证,那些不需要更高可靠性的用例不支付其实施成本;总是可以在基本的基础上增加更强的可靠性,但是为了获得更高的性能,不可能主动地去除可靠性。

讨论:消息排序

规则更具体地说,对于给定的一对Actor,直接从第一个发送到第二个的消息不会无序接收。这个词直接强调,这种保证仅适用于与告诉操作员一起发送到最终目的地,而不是在使用调解员或其他信息传播功能时(除非另有说明)。

他保证说明如下:

Actor A1 sends messages M1M2M3 to A2

Actor A3 sends messages M4M5M6 to A2

意味着:

1.如果M1已交付,则必须在M2和M3之前交付

2.如果M2已交付,则必须在M3之前交付

3.如果交付M4,则必须在M5和M6之前交付

4.如果M5已交付,则必须在M6之前交付

5.A2可以看到来自A1的消息与来自A3的消息交织

6.由于没有保证传送,因此可以丢弃任何消息,即不到达A2

请务必注意,Akka的保证适用于邮件排入收件人邮箱的顺序。如果邮箱实现不遵守FIFO顺序(例如PriorityMailbox),那么actor的处理顺序可能会偏离排队顺序。

请注意,此规则不具有传递性:

Actor A sends message M1 to actor C

Actor A then sends message M2 to actor B

Actor B forwards message M2 to actor C

Actor C may receive M1 and M2 in any order

因果传递排序意味着在Actor C的M1之前从未接收过M2(尽管其中任何一个都可能丢失)。当A,B和C驻留在不同的网络主机上时,由于不同的消息传递延迟,可能会违反此排序,请参阅下文。

沟通失败

请注意,上面讨论的排序保证仅适用于Actor之间的用户消息。actor的孩子的失败是通过相对于普通用户消息未被排序的特殊系统消息来传达的。特别是:

Child actor C sends message M to its parent P

Child actor fails with failure F

Parent actor P might receive the two events either in order MF or F, M

原因是内部系统消息具有自己的邮箱,因此用户和系统消息的排队调用的排序不能保证其出队时间的排序。

In-JVM(本地)消息发送规则

建议不要依赖本节中更强的可靠性,因为它会将您的应用程序绑定到仅本地部署:应用程序可能必须以不同的方式设计(而不是仅仅采用某些参与者本地的一些消息交换模式)才能适合在一组机器上运行。我们的信条是“设计一次,按照您希望的方式进行部署”,为实现这一目标,您应该只依赖于“一般规则”。

Akka测试套件依赖于不丢失本地上下文中的消息(以及用于远程部署的非错误条件测试),这意味着我们确实尽最大努力保持测试稳定。但是,本地tell操作可能会失败的原因与JVM上的普通方法调用相同:

  • StackOverflowError
  • OutOfMemoryError
  • other VirtualMachineError

此外,本地发送可能会以特定于Akka的方式失败:

  • 如果邮箱不接受该邮件(例如完整的BoundedMailbox)
  • 如果接收方在处理消息时失败或已经终止

虽然第一个是配置问题,但第二个值得一些考虑:如果在处理时出现异常,则消息的发送者不会得到反馈,而是通知发送给主管。这通常无法与外部观察者丢失的信息区分开来。

本地消息发送的排序

假设严格的FIFO邮箱,在某些条件下消除了上述消息排序保证的非传递性警告。正如您将注意到的,这些都是非常微妙的,未来的性能优化甚至可能使整个段落无效。

  • 在收到来自顶级actor的第一个回复之前,有一个锁保护内部临时队列,这个锁是不公平的;这意味着可以根据低级线程调度重新排序来自在演员构造期间到达的不同发送者的入队请求(比喻地,细节更多涉及)。由于JVM上不存在完全公平的锁,因此这是不可修复的。
  • 在构建路由器期间使用相同的机制,更确切地说是路由的ActorRef,因此使用路由器部署的actor存在同样的问题。
  • 如上所述,问题发生在排队期间涉及锁定的任何地方,这也可能适用于自定义邮箱。

此列表已经过仔细编译,但其他有问题的情况可能已经逃脱了我们的分析。

更高层次的抽象

 基于Akka核心的小而一致的工具集,Akka还提供了强大的,更高级别的抽象。

如上所述,对可靠传送要求的直接回答是明确的ACK-RETRY协议。这是最简单的形式;

  • 一种识别单个消息以将消息与确认相关联的方法
  • 重试机制,如果未及时确认,将重新发送消息
  • 接收器检测和丢弃重复的方法

Dead Letters

无法传递的消息(并且可以确定这些消息)将被传递给名为/ deadLetters的合成actor。这种交付是在尽力而为的基础上进行的;它甚至可能在本地JVM内失败(例如在Actor终止期间)。通过不可靠的网络传输发送的消息将丢失而不会显示为dead letter。

此工具的主要用途是用于调试,特别是如果actor发送不一致(通常检查死信会告诉您发送者或收件人在途中某处设置错误)。为了有用于此目的,最好避免在可能的情况下发送到deadLetters,即不时使用合适的死信记录器运行应用程序(请参阅下面的详细信息)并清理日志输出。这个练习就像所有其他一样 - 需要明智地应用常识:很可能避免发送给已终止的演员使发送者的代码比调试输出清晰度更复杂。

死信服务遵循与所有其他消息发送相同的交付保证规则,因此不能用于实现有保证的交付。

我如何收到Dead Letter?

actor可以在事件流上订阅类akka.actor.DeadLetter,请参阅事件流以了解如何执行此操作。然后,订阅的演员将从该点开始接收在(本地)系统中发布的所有DeadLetter。DeadLetter不会通过网络传播,如果要在一个地方收集死信,则必须为每个网络节点订阅一个参与者并手动转发它们。还要考虑在该节点生成DeadLetter,这可以确定发送操作失败,远程发送可以是本地系统(如果不能建立网络连接)或远程发送(如果发送的是Actor)在那个时间点不存在)。

DeadLetter(通常)并不令人担忧

每当一个Actor按照自己的决定终止时,它发送给自己的某些消息就有可能丢失。有一个在复杂的关闭场景中很容易发生,通常是良性的:看到akka.dispatch.Terminate消息被丢弃意味着给出了两个终止请求,但只有一个可以成功。同样地,你可能会看到akka.actor.Terminated来自子节点的消息,同时如果父节点在终止时仍在观看子节点。

未完待续!

原文:https://doc.akka.io/docs/akka/2.5/general/message-delivery-reliability.html

© 著作权归作者所有

共有 人打赏支持
woshixin
粉丝 27
博文 317
码字总数 252471
作品 0
杭州
程序员
私信 提问
Scala笔记整理(九):Actor和AKKA

[TOC] 概述 Scala的Actor有点类似于Java中的多线程编程。但是不同的是,Scala的Actor提供的模型与多线程有所不同。Scala的Actor尽可能地避免锁和共享状态,从而避免多线程并发时出现资源争用...

xpleaf
2018/04/24
0
0
Akka和Actor一起工作的消息《ten》译

Dependency 在项目中添加以下依赖项: Introduction 在前面的主题解说中,我们解释了如何构建大型的Actor系统,即如何表示组件,如何在层次结构中排列Actor。在这一部分中,我们将通过实现设...

woshixin
2018/08/29
0
0
scala系统导出大文件问题解决方案

这周遇到了一个技术难题,我们系统中的导出文件功能虽然早已完成,但是当导出超过8MB的文件时就会提示GC overhead,一开始只把问题定位到缓冲区不够,所以试图找到一条分批查询的方案,经过一定时...

金明略
2017/03/04
0
0
Akka简单的性能测试

因为最近工作的关系,要把异步任务从应用服务器中拆分到专门的异步处理服务器中. 方案一 是采用MQ的方式将任务消息发出,在服务端进行处理,如下图所示: Sample Flowchart Template (2).pn...

闪电
2016/08/22
78
0
Akka框架基本要点介绍

Akka基于Actor模型,提供了一个用于构建可扩展的(Scalable)、弹性的(Resilient)、快速响应的(Responsive)应用程序的平台。本文基本上是基于Akka的官方文档(版本是2.3.12),通过自己的...

东风125
2015/11/28
120
2

没有更多内容

加载失败,请刷新页面

加载更多

RabbitMQ入门

RabbitMQ是一个由erlang开发的基于AMQP(Advanced Message Queue)协议的开源实现。用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面都非常的优秀。是当前最主流的消息中间...

watermelon11
今天
14
0
今天的学习

自动加载:方法一 function __autoload( $className ){在这里,完成加载B这个类文件的工作。}class A{} //这是一个类$a1 = new A(); //这里没有自动加载的发生,因为A这个类...

墨冥
今天
2
0
印刷工艺步骤

印刷厂从收到订单到交付整个流程,一般涉及到以下步骤 1.设计(经过软件如cdr,psd,ai等等设计需要印刷的名片,宣传单,画册等物料); 2.排版拼版(在电脑软件这区域完成); 3.出版、出硫...

focusone
昨天
2
0
virtualbox中安装ubuntu

virtualbox+ubuntu 安装virtualbox,当前版本是6.0.4 下载ubuntu安装盘,建议lubuntu,链接是http://mirrors.ustc.edu.cn/ubuntu-cdimage/lubuntu/releases/18.04.2/release/lubuntu-18.04.......

chuqq
昨天
5
0
exists 谓词的子查询

https://blog.csdn.net/qq_19782019/article/details/78730882

仟昭
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部