我实施RabbitMQ在另一台服务器上执行一些图像编辑操作。虽然,在源映像同步之前,请求可能会不时地到达该服务器 - 在这种情况下,我希望在队列中弹回消息并在所有其他操作完成后处理它。
但是,使用重新提交位设置调用basic.nack会使我的队列立即重新接收该消息 - 在任何可以实际完成的操作之前。
目前我觉得我被迫实施一些逻辑,只是将原始邮件重新提交给交易所,但我想避免这种情况。两者都是因为同一条消息可能已在另一台服务器上成功处理(使用它自己的队列),并且因为我认为这是一个很常见的模式,所以必须有更好的方法。
(哦,我在消费者和服务器代码中使用php-amqplib)
谢谢!
更新:我使用死信交换解决了我的问题,如zaq178miami所建议
我目前的解决方案:
$dead_letter_exchange
$worker
$recovery_exchange
$dead_queue
,x-message-ttl
为5秒,x-dead-letter-exchange
设置为$recovery_exchange
$dead_letter_queue
绑定到$dead_letter_exchange
$worker
绑定到$recovery_exchange
$dead_letter_exchange
和$recovery_exchange
是生成的名称,基于我消费的交换和$worker
的价值让每个收到nack的消息在五秒钟后重新返回到该特定队列(服务器)上的worker。我可能仍然希望应用一些在$n
重试后将消息抛弃的逻辑。
我仍然愿意接受更好的想法; - )
答案 0 :(得分:1)
看起来你有竞争条件'问题是导致问题的原因。也许延迟消息发布或发布延迟消息是一个很好的选择,以确保图像同步到目标机器或在图像到达时发布消息(这可能很棘手)或只是按需同步图像(消息消耗时)。您甚至可以添加一些API来获取源图像,这样您就可以随时水平扩展您的消费者。我们的想法是让消费者尽可能地保持原子性和不可靠性。
回到原始问题,如果它是您的选项,请尝试Dead Letter Exchanges将失败的邮件移至单独的队列。混合失败的消息并且有效而没有确定的机制来检测重新发布的气味(由于潜在的循环问题,管理困难等原因)。但它确实取决于您的需求,消息率和硬件,如果某些解决方案产生稳定的结果并且您确定它 - 只需坚持下去。
注意,如果您使用的是php-amqplib,则可以同时开始使用来自多个队列的消息,这样您就可以使用主队列中的消息和推迟的消息(但是在这种情况下,您必须将消息发布到推迟的队列也被推迟,以防止它立即消耗)。
通常通过per-message或per-queue ttl和额外队列完成延迟消息发布,DLX设置为主工作队列,或者在您的情况下为推迟消息队列。