【问题标题】:How Akka.Net handles system falts during message processingAkka.Net 在消息处理过程中如何处理系统故障
【发布时间】:2026-01-30 13:55:01
【问题描述】:

假设一个集群节点收到一条消息,并且其中一个参与者开始处理它。在中间的某个地方,这个节点由于某种原因死亡。消息会发生什么,我的意思是它会被另一个可用节点处理还是会丢失?

【问题讨论】:

    标签: akka.net akka-cluster


    【解决方案1】:

    默认情况下,akka(以及所有其他参与者模型框架)提供最多一次交付。这意味着使用尽力保证将消息发送给参与者 - 如果它们无法到达目标,它们将不会被重新传递。这也意味着,如果消息到达目标,但与之关联的进程在完成之前被中断,则不会重试

    话虽如此,有很多方法可以在具有各种保证的演员之间提供重新交付。

    1. 最简单和最不可靠的方法是结合使用Ask 模式和Polly 库。但是,如果发送者所在的节点死亡,这将无济于事 - 仅仅是因为消息仍然只存储在内存中。
    2. 更可靠的模式是在集群前使用一些事件日志/队列(即 Azure 服务总线、RabbitMQ 或 Kafka)。在这种方法中,客户端通过总线/队列发送请求,而流程管道中的第一个参与者负责接收它。如果管道中的某个参与者或节点死亡,则会重试该消息的整个管道。
    3. 另一个想法是使用 Akka.Peristence 模块中的at-least-once delivery。它允许您使用持久性参与者的事件源功能来持久化消息。但是,IMO 需要对 Akka 有一点经验。

    所有这些方法都提供了至少一次传送保证,这意味着可以多次将相同的消息发送到其目的地。这也意味着,您的处理逻辑需要通过幂等行为或通过在接收方识别和删除重复项来确认这一点。

    【讨论】: