如何防止 RabbitMQ 中的死字重复?

How to prevent duplicates in RabbitMQ dead lettering?

首先,抱歉标题不好!我找不到任何与此问题匹配的具体内容,并且在 Google 或 Whosebug 上找不到任何关于此问题的内容。

所以首先是一些背景知识,我有一个基于 php-amqplib\Thumper 的 RabbitMQ 消费者并且成功的消息消费一切正常并且符合预期。

但是,我有一个方法,它是 RabbitMQ 的回调,每次它向消费者发送消息时,都会触发此回调。

我将它包裹在一个 try catch 中,这样,如果一条消息无法处理,我可以设置一个 retry_count header,一旦该消息第三次返回,例如retry_count: 3我发给一个死人queue,发个basic_nack.

但是,这就是我的问题所在,我的死机 queue 中的每条消息都收到超过 1 条消息,即对于每条失败的消息,2 条消息出现在我的死机 queue 中一个具有正确的 dead queue 属性。例如

delivery_mode: 2 headers:<br> x-death:<br> 计数:1 原因:拒绝 queue: ee.api.events.medusa 时间:1498730321 交换:EES_ApiEvents routing-keys: ee.api.events.medusa.WALLET.UPDATE

另一个,只有 delivery_mode 而没有其他属性,我一辈子都弄不明白这条多余的消息是从哪里来的!

这是 retry_count 达到 3 时 运行 的代码位:

        $producer
            ->setDurableExchange(true)
            ->setExchangeType(Producer::RABBITMQ_EXCHANGE_TYPE_TOPIC)
            ->setExchangeAutodelete(false)
            ->setExchangeName($deadExchangeName)
            ->setQueueName($deadQueueName)
            ->setRoutingKey($routingKey)
            ->setBindings([
                $routingKey,
            ]);

        $producer->publish(Json::decode($message->body, true));

        $message->delivery_info['channel']->basic_nack($deliveryTag, false, false);

提前致谢!

所以在玩了很多次之后,我回到文档并重新阅读,它清楚地指出,如果你用 requeue=false 拒绝一条消息,那么它会自动被死信,如果你定义了一个死信与主队列交换信件。

那么问题就解决了!