Akka: почтовый ящик актера восстанавливается после сбоя / перезапуска системы актера?

Я пытаюсь реализовать Saga (Process Manager) с PersistentActor, который обновляет несколько сущностей / совокупных корней для достижения (конечной) согласованности без транзакции ACID.

Скажем, в середине процесса, между получением сообщения диспетчером процессов и началом его обработки, произошел сбой jvm.

Или приложение в данный момент разворачивается заново.

Будет ли почтовый ящик диспетчера процессов восстановлен после перезапуска jvm (вместе с системой акторов)?


person Teimuraz    schedule 12.01.2018    source источник


Ответы (2)


Почтовые ящики не восстанавливаются в случае сбоя JVM. Ответственность за то, чтобы его сообщение было получено / сохранялась, лежит на отправителе. Между постоянными участниками используйте At -Минимальная доставка.

person Frederic A.    schedule 13.01.2018
comment
Значит ли это, что если отправитель использует доставку по крайней мере один раз и jvm вылетает после того, как отправитель отправил сообщение и до того, как получатель получил его, это сообщение будет повторно отправлено после перезапуска системы jvm / субъект? - person Teimuraz; 13.01.2018
comment
Короткий ответ - да, чуть более длинный ответ - то, что по истечении тайм-аута отправитель заметит, что он не получил ожидаемого подтверждения доставки, и отправит его повторно. Это также работает, если отправитель вылетает. - person Frederic A.; 15.01.2018

Учитывая, что вы уже используете PersistentActor, разумно использовать его функции AtLeastOnceDelivery для того, что вам нужно. AtLeastOnceDelivery по существу гарантирует, что действующий субъект-отправитель будет продолжать отправлять сообщения получателю с настраиваемой частотой, пока он не получит подтверждение от получателя (или от некоторой процедуры завершения для отмены текущих попыток доставки).

Как и в случае с обычным PersistentActor (с AtLeastOnceDelivery или без него), сохраняемые сообщения будут повторно отправлены в случае сбоя JVM. В случае AtLeastOnceDelivery сохраненные сообщения будут повторно отправлены после восстановления системы до получения подтверждения. Akka предоставляет метод deliver для отправки каждого сообщения, помеченного последовательным монотонно возрастающим deliveryId, и, получив подтверждение с соответствующим deliveryId от получателя, использует метод confirmDelivery для сигнализации успешной доставки сообщения.

Следующий фрагмент, который является частью образца кода из соответствующего Akka doc, выделяет ключевую логику AtLeastOnceDelivery в классе актора-отправителя (который extends PersistentActor with AtLeastOnceDelivery). Обратите внимание, что один и тот же обработчик сохраняемости updateState используется для сохранения событий, соответствующих deliver и confirmDelivery, для согласованного восстановления состояния:

override def receiveCommand: Receive = {
  case s: String =>
    persist(MsgSent(s))(updateState)
  case Confirm(deliveryId) =>
    persist(MsgConfirmed(deliveryId))(updateState)
}

override def receiveRecover: Receive = {
  case evt: Evt => updateState(evt)
}

def updateState(evt: Evt): Unit = evt match {
  case MsgSent(s) =>
    deliver(destination)(deliveryId => Msg(deliveryId, s))
  case MsgConfirmed(deliveryId) =>
    confirmDelivery(deliveryId)
}
person Leo C    schedule 14.01.2018