【问题标题】:akka and the benefits of at-most-once message semanticsakka 和最多一次消息语义的好处
【发布时间】:2020-10-28 07:45:06
【问题描述】:

我正在阅读本教程:https://doc.akka.io/docs/akka/current/typed/guide/tutorial_3.html,但不太明白什么时候最多一次消息语义更可取,因为虽然我们获得了性能提升,但我们失去了消息的弹性。看起来这里解释了这种权衡的理由:

我们只想在订单实际完全处理并保留后报告成功。唯一可以报告成功的实体是应用程序本身,因为只有它对所需的域保证有任何了解。没有通用的框架可以弄清楚特定领域的细节以及在该领域中什么被认为是成功的。 在这个特定的示例中,我们只想在数据库写入成功后发出成功信号,其中数据库确认订单现在已安全存储。由于这些原因,Akka 将保证责任提升到应用程序本身,即您必须使用 Akka 提供的工具自己实现它们。这使您可以完全控制要提供的保证。现在,让我们考虑 Akka 提供的消息排序,以便于推理应用程序逻辑。

,但我不太明白这是什么意思。感谢您在理解此决定或其他一些考虑因素方面提供的任何帮助。

我阅读了这个线程RPC semantics what exactly is the purpose,它似乎提供了一个关于最多一次语义的用例的明确定义,其中支付提交是您不想复制的示例。但是从上面引用的段落中,听起来消息将被发送到以太中,而不考虑确认消息传递成功或失败的 ack。我想知道最多一次语义的两种描述是否对它们各自的域都是正确的,如何通过来自 akka 的确认来获取另一个 stackoverflow 线程中的行为。

【问题讨论】:

    标签: akka


    【解决方案1】:

    所有不了解域的任何事情都可以通过至少或恰好一次传递提供的是消息已被传递(保证消息已被处理也是可能的并且至少在某些情况下是可行的(但不是所有)场景)。如果这是您想要的,这很好,但是将其与更高级别的东西(例如“订单已被持久记录”)混为一谈几乎肯定会导致基本上无法调试错误。

    至少一次在 Akka 中很容易实现,方法是让消息包含一个包含 ActorRef 的字段,向其发送确认(或其他响应)并让发件人重新发送未确认的消息(因为它极有可能ack 被丢弃,这些重试会导致至少一次)。 ask 模式(包含在 Akka 中)在高级别的方面提供了这一点:在 Akka Typed 中,这是通过指定一个适配器函数来完成的,这样当参与者 A 请求参与者 B 时,B 可以在其协议中发送消息,而 A 在其协议中获取消息协议(避免先有鸡还是先有蛋的问题);如果在指定的时间范围内没有收到响应,适配器会导致向参与者 A 发送失败消息(对于至少一次语义将指示 A 最终重试该消息)。需要记住的关键是,决定是否响应以及何时响应的是参与者 B(或其指定人员:例如,如果 B 将工作分配给工作参与者,那么该工作参与者可以向 A 发送确认)决定是否响应以及何时响应,而不是 Akka。

    如果至少执行一次,围绕幂等性设计消息传递协议非常有用:成功消息的重试不会导致超出 ack 的副作用。幂等性加至少一次被称为“有效一次”,它比完全一次更容易实现且重量更轻。

    Akka's docs on interaction patterns 描述了 Akka 中的各种消息传递模式,并讨论了优缺点。最近,尤其是在使用 Akka Cluster 和 Akka Persistence 时,有一个相当重量级的 reliable delivery 实现:在最大可靠性模式下(使用 Akka Persistence),因为以这种方式发送的每条消息都被持久化到数据存储区(例如本地磁盘,或cassandra,或...),消息发送的延迟会大大增加。

    【讨论】:

      猜你喜欢
      • 2012-11-14
      • 2019-02-27
      • 1970-01-01
      • 1970-01-01
      • 2019-07-26
      • 2020-05-12
      • 1970-01-01
      • 2016-09-08
      • 1970-01-01
      相关资源
      最近更新 更多