Akka.Net 如何在消息处理期间处理系统故障

How Akka.Net handles system falts during message processing

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

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

话虽这么说,但有许多方法可以在具有各种保证的参与者之间提供重新交付。

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

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