RabbitMQ PRECONDITION_FAILED - 未知的交付标签

2022-08-30 19:44:11

我们有一个PHP应用程序,它通过WebSocket连接将消息从RabbitMQ转发到连接的设备(PHP AMQP pecl扩展v1.7.1和RabbitMQ 3.6.6)。

消息从队列数组(每个 websocket 连接 1 个)使用,当我们通过 websocket 收到消息已接收的确认时,使用者会确认消息(因此我们可以将未在可接受的时间范围内传递的消息重新排队)。这是以非阻塞方式完成的。

99%的情况下,这很完美,但偶尔我们会收到错误“RabbitMQ PRECONDITION_FAILED - 未知的交付标签”。这将关闭通道。在我的理解中,此异常是以下条件之一的结果:

  1. 邮件已被确认或拒绝。
  2. 尝试通过未传递消息的通道进行 ack。
  3. 在消息超时 (ttl) 过期后尝试进行 ack。

我们已经为上述每种情况实施了保护措施,但问题仍然存在。

我意识到有许多实现细节可能会影响这一点,但是在概念层面上,是否有任何其他失败案例我们没有考虑过,应该处理?还是有更好的方法来实现上述功能?


答案 1

“PRECONDITION_FAILED - 未知传递标记”通常是由于双重确认、错误通道上的确认或不应被确认的消息而发生的。

因此,在相同情况下,您将执行两次或使用另一个通道basic.ackbasic.ack


答案 2

(解决方案如下)

引用Jan Grzegorowski在他的博客中的话:

如果您正在与本文标题中包含的406错误消息作斗争,您可能有兴趣阅读整个故事。

问题

我使用amqplib将基于NodeJS的消息处理器与RabbitMQ代理连接起来。一切似乎都运行正常,但日志中不时显示 406(预处理失败)消息:

"Error: Channel closed by server: 406 (PRECONDITION-FAILED) with message "PRECONDITION_FAILED - unknown delivery tag 1"

溶液 <--

保持简单:

  • 您必须按照消息到达系统时的相同顺序确认消息
  • 您不能在与到达消息不同的通道上确认消息,如果您违反这些规则中的任何一个,您将面临 406(前提条件失败)错误消息。

原始答案


推荐