Akka和Actor一起工作的消息《ten》译

Dependency

在项目中添加以下依赖项:

Introduction

    在前面的主题解说中,我们解释了如何构建大型的Actor系统,即如何表示组件,如何在层次结构中排列Actor。在这一部分中,我们将通过实现设备Actor来查看。

    如果我们使用对象,我们通常会将API设计为接口,这是由实际实现填充的抽象方法的集合。在Actor的世界中,协议取代了接口。虽然不可能在编程语言中形式化通用协议,但我们可以编写它们最基本的元素,即消息。因此,我们将首先确定要发送给设备Actor的消息。

    通常,消息属于类别或模式。通过识别这些模式,您会发现在它们之间进行选择并实现它们变得更加容易。第一个示例演示了请求 - 响应消息模式。

识别设备的消息

    设备Actor的任务很简单:

  • 收集温度测量值
  • 请求时,报告最后测量的温度

    但是,设备可能在没有立即进行温度测量的情况下启动。因此,我们需要考虑温度不存在的情况。这也允许我们在没有写入部分的情况下测试Actor的查询部分,因为设备Actor可以报告空结果。

    用于从设备Actor获得当前温度的协议是简单的:

  • 1.等待当前温度的请求。
  • 2.询问时,报告最后测量的温度(询问时,报告最后测量的温度或者当前温度不可用)。

    我们需要两条消息,一条用于请求,另一条用于回复。我们的第一次尝试可能如下所示:

    这两条消息似乎涵盖了所需的功能。但是,我们选择的方法必须考虑应用程序的分布式特性。虽然与本地JVM上的Actor进行通信的基本机制与远程Actor相同,但我们需要牢记以下几点:

  • 本地和远程消息之间的传递延迟将存在可观察到的差异,因为网络链路带宽和消息大小等因素也会导致这个。
  • 可靠性是一个问题,因为远程消息发送涉及更多步骤,这意味着更多可能出错。
  • 本地发送将在同一JVM内传递对该消息的引用,对发送的基础对象没有任何限制,而远程传输将对消息大小设置限制。

    此外,虽然在同一个JVM内部发送更可靠,但如果一个Actor在处理消息时由于程序错误而失败,则效果与远程主机在处理消息时由于远程主机崩溃而失败的效果相同。即使在这两种情况下,服务都会在一段时间后恢复(Actor由其管理者重新启动,主机由运营商或监控系统重新启动)在崩溃期间各个请求都会丢失。因此,Actor使得每条消息都可能丢失是悲观的赌注。

    但是为了进一步理解协议的灵活性需求,它将有助于考虑Akka消息排序和消息传递保证。Akka为消息发送提供以下行为。

  • 最多一次传递,即无保证交货。
  • 每个发送者,接收者对维护消息排序。

    以下部分更详细地讨论了此行为:

消息传递

消息传递子系统提供的传递语义通常分为以下几类:

  • At-most-once delivery :每条消息传递零次或一次;在更多的因果关系中,这意味着消息可能会丢失,但永远不会重复。
  • At-least-once delivery :可能会多次尝试传递每条消息,直到至少有一条消息成功;再次,在更多的因果方面,这意味着消息可以重复,但永远不会丢失。
  • Exactly-once delivery:每封邮件只发送一次给收件人;消息既不会丢失也不会重复。

    第一种行为,即Akka使用的行为,是最便宜的,并且性能最高。它具有最少的实现开销,因为它可以以一种即发即忘的方式完成,而不会将状态保持在发送端或传输机制中。第二个,至少一次,需要重试以抵消运输损失。这增加了将状态保持在发送端并在接收端具有确认机制的开销。完全一次交付是最昂贵的,并且导致最差的性能:除了至少一次交付所增加的开销之外,它还要求将状态保持在接收端以便过滤掉重复的交付。

    在Actor系统中,我们需要确定保证的确切含义 - 系统在何时将交付视为已完成:

  1. 什么时候消息在网络上发送出去?
  2. 什么时候目标Actor收到消息?
  3. 什么时候消息被放入目标Actor的邮箱时?
  4. 什么时候消息目标Actor开始处理消息?
  5. 目标Actor何时成功处理了该消息?

    大多数声称保证交付的框架和协议实际上提供了类似于第4点和第5点的内容。虽然这听起来合理,但它实际上有用吗?要了解其含义,请考虑一个简单实用的示例:用户尝试下订单,我们只想声明它已经成功处理,一旦它实际上在订单数据库中的磁盘上。

    如果我们依赖于成功处理消息,则只要订单已提交给负责验证它的内部API,处理它并将其放入数据库,Actor就会报告成功。不幸的是,在调用API之后,可能会发生以下任何一种情况:

  1. 主机可能崩溃。
  2. 反序列化可能会失败。
  3. 验证可能会失败。
  4. 数据库可能不可用。
  5. 可能会发生编程错误。

    这表明交付保证不会转化为域级保证。我们只想在订单实际完全处理和保留后报告成功。可以报​​告成功的唯一实体是应用程序本身,因为只有它对所需的域保证有任何了解。没有通用框架可以确定特定域的细节以及在该域中被认为是成功的。

    在这个特定的例子中,我们只希望在成功的数据库写入之后发出成功信号,数据库确认订单现在已安全存储。由于这些原因,Akka将保证的责任提升到应用程序本身,即您必须自己实现它们。这使您可以完全控制要提供的保证。现在,让我们考虑Akka提供的消息排序,以便于推理应用程序逻辑。

消息顺序

    在Akka中,对于给定的一对Actor,从第一个发送到第二个的消息不会无序接收。

    如果:

    Actor A1将消息M1,M2,M3发送到A2。

    Actor A3将消息M4,M5,M6发送到A2。

    这意味着,对于Akka消息:

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

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

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

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

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

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

    这些保证达到了很好的平衡:让一个Actor的消息按顺序到达对于构建易于推理的系统是方便的,而另一方面允许来自不同Actor的消息交错到达提供足够的自由来有效地实现Actor系统。

    有关交付保证的完整详细信息,请参阅参考页面reference page.。

原文:https://doc.akka.io/docs/akka/2.5/guide/tutorial_3.html

有什么讨论的内容,可以加我公众号:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值