如何一条一条消费RabbitMQ死信队列中的消息
How to consume message from RabbitMQ dead letter queue one by one
要求是通过公开 REST 服务来处理来自死信队列的消息 API(Spring 引导)。
这样一旦调用REST服务,就会从DL队列中消费一条消息,重新发布到主队列中进行处理。
@RabbitListener(queues = "QUEUE_NAME") 立即使用消息,根据场景不需要。该消息仅需由 REST 服务使用 API。
有什么建议或解决方案吗?
我认为 RabbitListener
对这里没有帮助。
但是您可以手动实现此行为。
Spring 引导自动创建 RabbitMq
连接工厂,因此您可以使用它。当进行 http 调用时,只需手动从队列中读取一条消息,您可以使用 basic.get 同步获取一条消息:
@Autowire
private ConnectionFactory factory
void readSingleMessage() {
Connection connection = null;
Channel channel = null;
try {
connection = factory.newConnection();
channel = connection.createChannel();
channel.queueDeclare(QUEUE_NAME, true, false, false, null);
GetResponse response = channel.basicGet(QUEUE_NAME, true);
if (response != null) {
//Do something with the message
}
} finally {
//Check if not null
channel.close();
connection.close();
}
}
如果您正在使用Spring;您可以使用 RabbitTemplate.receive(...)
.
避免其他答案中的所有样板
编辑
要手动 ack/reject 消息,请改用 execute
方法。
template.execute(channel -> {
GetResponse got = channel.basicGet("foo", false);
// ...
channel.basicAck(got.getEnvelope().getDeliveryTag(), false);
return null;
});
级别有点低,但同样,大部分样板文件都已为您处理。
要求是通过公开 REST 服务来处理来自死信队列的消息 API(Spring 引导)。 这样一旦调用REST服务,就会从DL队列中消费一条消息,重新发布到主队列中进行处理。 @RabbitListener(queues = "QUEUE_NAME") 立即使用消息,根据场景不需要。该消息仅需由 REST 服务使用 API。 有什么建议或解决方案吗?
我认为 RabbitListener
对这里没有帮助。
但是您可以手动实现此行为。
Spring 引导自动创建 RabbitMq
连接工厂,因此您可以使用它。当进行 http 调用时,只需手动从队列中读取一条消息,您可以使用 basic.get 同步获取一条消息:
@Autowire
private ConnectionFactory factory
void readSingleMessage() {
Connection connection = null;
Channel channel = null;
try {
connection = factory.newConnection();
channel = connection.createChannel();
channel.queueDeclare(QUEUE_NAME, true, false, false, null);
GetResponse response = channel.basicGet(QUEUE_NAME, true);
if (response != null) {
//Do something with the message
}
} finally {
//Check if not null
channel.close();
connection.close();
}
}
如果您正在使用Spring;您可以使用 RabbitTemplate.receive(...)
.
编辑
要手动 ack/reject 消息,请改用 execute
方法。
template.execute(channel -> {
GetResponse got = channel.basicGet("foo", false);
// ...
channel.basicAck(got.getEnvelope().getDeliveryTag(), false);
return null;
});
级别有点低,但同样,大部分样板文件都已为您处理。