2015-03-16 1 views
2

Я пытаюсь выяснить, какая гарантия доставки сообщений поддерживает Akka. Я пришел к следующему выводу:Akka Message Delivery Guarantees

В-самый раз: поддерживается по умолчанию

По-крайней мере, один раз: Поддерживается Akka Постоянство

Ровно-один раз?

Поддерживает ли Akka ровно один раз? Как я смогу достичь этого, если это не так?

+0

Применение специальных идентификаторов могут быть использованы для сообщений, передаваемых для обнаружения и отбрасывать дубликаты, пожалуйста, проверьте, https://groups.google.com/forum/#! topic/akka-user/Wy1E5aGJPqA – Karthikeyan

+2

Еще одна ссылка для интуитивного понимания того, почему однократно невозможно в отказоустойчивых системах, http://brooker.co.za/blog/2014/11/15/exactly-once.html – Karthikeyan

+0

Вы также можете посмотреть на Надежный шаблон прокси. Не может быть именно то, что вы ищете, но в том же районе. http://doc.akka.io/docs/akka/2.3.9/contrib/reliable-proxy.html – cmbaxter

ответ

6

Akka из коробки обеспечивает доставку по принципу «как только», как вы обнаружили. At-Least-Once доступен в некоторых библиотеках, таких как Akka Persistence, и вы можете легко создать его самостоятельно, создав в своих актерах протокол 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-После обработки, приемник должен гарантировать, что повторные экземпляры одного и того же сообщения приведет только к работе, проводимой один раз. Это может быть достигнуто за счет выполнения работы, выполняемой приемником idempotent, чтобы он мог быть повторно применен, или путем приема получателем записи о том, что он уже обработал. Для At-Мост-Once ответственность лежит с приемником:

class AtMostOnceReceiver extends Actor { 

    var workDone = false 

    def receive = { 

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

}