如何防止 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
拒绝一条消息,那么它会自动被死信,如果你定义了一个死信与主队列交换信件。
那么问题就解决了!
首先,抱歉标题不好!我找不到任何与此问题匹配的具体内容,并且在 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
拒绝一条消息,那么它会自动被死信,如果你定义了一个死信与主队列交换信件。
那么问题就解决了!