java spring rabbit - 优雅地拒绝消息
java spring rabbit - gracefully reject a message
我有以下侦听器方法:
@Override
public void onMessage(Message message, Channel channel) {
try {
// do something bad :)
} catch (Exception e){
try {
long dt = null != message.getMessageProperties()
? message.getMessageProperties().getDeliveryTag()
: 0;
channel.basicReject(dt, true);
} catch(IOException io) {
logger.error("IO-COMMON", io);
}
}
}
问题是基本拒绝不起作用,我不知道为什么。如何优雅地拒绝?我认为如果我拒绝一条消息,它应该重新排队并驻留在缓存中,然后再转到下一个工作人员。但实际上这条消息好像丢了。
如果您自己进行确认,则需要将确认模式设置为手动。我不确定为什么它不适合你; DEBUG/TRACE 日志记录可能会有帮助。
您应该考虑让容器处理 acks - 使用 acknowledgemode=AUTO
;如果侦听器 returns 正常,容器通常会为抛出的任何异常重新排队消息或确认消息。
您可以将 defaultRequeueRejected
设置为 false(默认为 true),消息将被丢弃(或路由到 DLX/DLQ)。
您还可以抛出一个 AmqpRejectAndDontRequeueException
来覆盖重新排队失败消息的默认机制。
如果 ack 模式是 NONE - 没有 ack,RabbitMQ 会在消息发送后立即自动 ack。
我有以下侦听器方法:
@Override
public void onMessage(Message message, Channel channel) {
try {
// do something bad :)
} catch (Exception e){
try {
long dt = null != message.getMessageProperties()
? message.getMessageProperties().getDeliveryTag()
: 0;
channel.basicReject(dt, true);
} catch(IOException io) {
logger.error("IO-COMMON", io);
}
}
}
问题是基本拒绝不起作用,我不知道为什么。如何优雅地拒绝?我认为如果我拒绝一条消息,它应该重新排队并驻留在缓存中,然后再转到下一个工作人员。但实际上这条消息好像丢了。
如果您自己进行确认,则需要将确认模式设置为手动。我不确定为什么它不适合你; DEBUG/TRACE 日志记录可能会有帮助。
您应该考虑让容器处理 acks - 使用 acknowledgemode=AUTO
;如果侦听器 returns 正常,容器通常会为抛出的任何异常重新排队消息或确认消息。
您可以将 defaultRequeueRejected
设置为 false(默认为 true),消息将被丢弃(或路由到 DLX/DLQ)。
您还可以抛出一个 AmqpRejectAndDontRequeueException
来覆盖重新排队失败消息的默认机制。
如果 ack 模式是 NONE - 没有 ack,RabbitMQ 会在消息发送后立即自动 ack。