Akka:演员系统崩溃/重启后演员的邮箱会恢复吗?



我试图使用PersistentActor实现Saga(进程管理器),该PersistentActor更新多个实体/聚合根以实现(最终)一致性,而无需ACID事务。

假设,在进程的中间,在进程管理器收到消息并开始处理它之间,jvm崩溃了。

或者此时正在重新部署应用程序。

进程管理器的邮箱是否会在 jvm(以及执行组件系统)重新启动后恢复?

邮箱在JVM 崩溃时不会恢复。发件人有责任确保其消息已接收/持久化。在持久性参与者之间,使用至少一次传递。

鉴于您已经在使用 PersistentActor,因此利用其 AtMinimumOnceDelivery 功能来满足您的需求是合理的。 AtMinimumOnceDelivery 本质上确保持久发送方参与者将继续以可配置的频率向接收方发送消息,直到它收到来自接收方的确认(或从取消正在进行的传递尝试的某些终止例程)。

与一般的 PersistentActor (有或没有 AtMinimumOnceDelivery)一样,如果 JVM 崩溃,将重新发送持久化的消息。 对于 AtMinimumOnceDelivery,持久化的消息将在系统恢复时重新发送,直到收到确认。 Akka提供了方法deliver,以发送标记有连续单调递增deliveryId的每条消息,并在收到来自接收方的相应deliveryId的确认后,使用方法confirmDelivery来表示消息的成功传递。

以下代码片段是相关 Akka 文档中的示例代码的一部分,突出显示了发送方参与者类(extends PersistentActor with AtLeastOnceDelivery)中的关键 AtMinimumOnceDelivery 逻辑。 请注意,相同的持久性处理程序updateState用于保留对应于deliverconfirmDelivery的事件,以实现一致的状态恢复:

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)
}

最新更新