如何可靠地处理队列?

Bar*_*lom 8 language-agnostic queue design-patterns transactions reliability

采取这个概念上简单的任务:消耗队列,为每个条目发送电子邮件.

一个简单的方法是:

while true:
   entry = queue.pop()
   sendMail();
Run Code Online (Sandbox Code Playgroud)

这里的问题是,如果消费者在弹出后但在发送邮件之前/期间崩溃,则邮件丢失.所以你把它改成:

while true:
   entry = queue.peek()
   sendMail();
   queue.pop();
Run Code Online (Sandbox Code Playgroud)

但是现在,如果消费者在邮寄之后崩溃,但在弹出之前,邮件将在消费者重新启动时再次发送.

处理这个问题的最佳实践方法是什么?

发送电子邮件只是一个例子,可以替代任何关键任务.还假设队列的弹出是已发送邮件的唯一记录,因此邮件子系统本身不记录任何内容.

Viv*_*vek 3

您的要求是否看起来像是试图解决两个将军问题(没有确定性解决方案/限制)?https://en.wikipedia.org/wiki/Two_Generals%27_Problem

窥视 - 处理 - 删除

您只想在确保成功处理后才删除,并确保正确删除。那么任何这些消息都可能丢失/程序可能在任何步骤崩溃。

大多数强大的消息队列依赖于一组 ack + 重复尝试(交付)来获得所需的行为(直到 ack 返回)。

但实际上不可能保证在每种情况下都有完美的行为。您只需要最终权衡可能性,并在重复(至少尝试)处理和“从不”(无限内存等)丢失消息之间做出工程折衷 - 具体到您的实际应用程序需求。这又不是一个新问题:),并且您不太可能需要为其编写临时代码 - 就像我提到的,大多数 MQ 都解决了这个问题。