Akka 消息传递保证

Posted

技术标签:

【中文标题】Akka 消息传递保证【英文标题】:Akka Message Delivery Guarantees 【发布时间】:2015-03-16 10:58:18 【问题描述】:

我正在尝试找出 Akka 支持的消息传递保证。我得出以下结论:

最多一次:默认支持

至少一次:支持 Akka 持久性

恰好一次:?

Akka 是否支持完全一次?如果没有,我怎么能做到这一点?

【问题讨论】:

应用程序特定的 ID 可用于传输的消息以检测和丢弃重复项,请检查,groups.google.com/forum/#!topic/akka-user/Wy1E5aGJPqA 另一个链接,可以直观地理解为什么在容错系统中不可能只使用一次,***er.co.za/blog/2014/11/15/exactly-once.html 您还可以查看可靠代理模式。可能不是您正在寻找的东西,但在同一个社区。 doc.akka.io/docs/akka/2.3.9/contrib/reliable-proxy.html 感谢您的链接。如果我理解正确,简短的回答是 Akka 不支持完全一次? 简短的回答是,在现实世界中不存在exactly-once。 【参考方案1】:

如您所见,开箱即用的 Akka 提供“最多一次”交付。 At-Least-Once 在某些库中可用,例如 Akka Persistence,您可以通过在您的 actor 中创建一个 ACK​​-RETRY 协议来相当轻松地自己创建它。发送者会定期发送消息,直到接收者确认收到。

简单地说,对于至少一次,责任在于发件人。例如在 Scala 中:

class Sender(receiver: ActorRef) extends Actor 

  var acknowledged = false

  override def preStart() 
    receiver ! "Do Work"
    system.scheduler.scheduleOnce(50 milliseconds, self, "Retry")
  

  def receive = 
    case "Retry" => 
      if(!acknowledged) 
        receiver ! "Do Work"
        system.scheduler.scheduleOnce(50 milliseconds, self, "Retry")
      

    case "Ack" => acknowledged = true
  


class Receiver extends Actor 

  def receive = 
    case "Do Work" => 
      doWork()
      sender ! "Ack"
  

  def doWork() = ...

但是对于 At-Most-Once 处理,接收方必须确保同一消息的重复实例只导致工作完成一次。这可以通过使接收者完成的工作具有幂等性来实现,以便可以重复应用,或者让接收者记录它已经处理的内容。对于最多一次,责任在于接收方:

class AtMostOnceReceiver extends Actor 

  var workDone = false

  def receive = 

    case "Do Work" =>
      if(!workDone) 
        doWork()
        workDone = true
      
      sender ! Ack
  


【讨论】:

以上是关于Akka 消息传递保证的主要内容,如果未能解决你的问题,请参考以下文章

akka消息传递

(转)Akka学习笔记

AkkaAkka 传递消息

Akka 基础概念

akka 流是不是提供有保证的交付

[scala] akka actor编程