在处理来自RabbitMQ的消息时出现异常时,我只想取消确认并将特定消息放回到差异队列中,或者重新排队到同一队列或完全丢弃该消息(根据最后一个布尔标志@ requeue in basicNack)。
整个想法是后来我可以得到unack消息的计数并检查消息格式等,而不是一次又一次地重新排队到同一个频道,我也希望将未确认的信号发送到当前频道。
仅供参考我将channel ack模式设置为手动(即container.setAcknowledgeMode(AcknowledgeMode.MANUAL);)
这就是我现在正在做的事情。
public class My***Listener implements ChannelAwareMessageListener{
try{
@Override
public void onMessage(Message message,Channel channel) throws Exception {
String s = new String(message.getBody());
//some logic
//after successful ack manually
channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
}
catch(Exception e){
//currently on exception i am unack the channel
channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,false);
}
任何帮助都非常值得赞赏。
答案 0 :(得分:4)
您可以将它们发送到死信队列。这是一个非常标准的模式。
答案 1 :(得分:3)
你需要这样的东西:
@Bean
RetryOperationsInterceptor interceptor() {
return RetryInterceptorBuilder.stateless()
.withMaxAttempts(5)
.setRecoverer(new RepublishMessageRecoverer(amqpTemplate(), "bar", "baz"))
.build();
}
注意:仅适用于spring-amqp 1.3+
另见Reference
答案 2 :(得分:1)
如果您更喜欢使用声明,请参阅this answer以获取示例。
要将邮件路由到DLX
,您可以将defaultRequeuRejected
设置为false
(在侦听器容器上)。或者你可以抛出一个AmqpRejectAndDontRequeueException
告诉容器你想要拒绝这个消息(而不是重新排队)。
容器的默认行为是重新排队被拒绝的邮件。
您可以使用带有RejectAndDontRequeueRecoverer
的重试拦截器来自动抛出异常;或者,正如@ Jawo99所说,您可以使用重新发布的恢复器 - 这具有将堆栈跟踪添加为标头的额外好处。 DLX只是路由原始邮件。