Akka消息传递保证

时间:2015-03-16 10:58:19

标签: akka

我试图找出Akka支持的消息传递。我得出以下结论:

  

最多一次:默认支持

     

至少一次:支持Akka Persistence

     

恰好一次:?

Akka是否支持一次?如果不是这样,我怎么能实现这个目标?

1 个答案:

答案 0 :(得分:8)

正如您所发现的那样,开箱即用的Akka提供了至多一次交付。 At-Least-Once可以在某些库中使用,例如Akka Persistence,您可以通过在actor中创建ACK-RETRY协议来轻松地创建它。发件人会定期发送消息,直到接收方确认收到消息。

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

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
  }

}