简体   繁体   English

将未确认的消息(异常时)放入RabbitMQ中的其他队列

[英]Put unacknowledged message(on exception) to a different queue in RabbitMQ

On exception while processing the message from RabbitMQ, i just wanted to unacknowledg and put back the particular message to a difference queue instead or re-queue to same queue or completely discard the message(as per the last Boolean flag@requeue in basicNack). 在处理来自RabbitMQ的消息时出现异常时,我只想取消确认并将特定消息放回到差异队列中,或者重新排队到同一队列或完全丢弃该消息(根据basicNack中的最后一个布尔标志@ requeue)。

The whole idea is later on i can get the count of unack message and check the message format etc instead of re-queue again and again to same channel and also i want to sent unacknowledged signal to current channel. 整个想法是稍后我可以得到unack消息的计数并检查消息格式等而不是一次又一次地重新排队到同一个频道,我也想要将未确认的信号发送到当前频道。

FYI I set the channel ack mode as manual(ie container.setAcknowledgeMode(AcknowledgeMode.MANUAL);) 仅供参考我将channel ack模式设置为手动(即container.setAcknowledgeMode(AcknowledgeMode.MANUAL);)

This is what i am doing now. 这就是我现在正在做的事情。

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);
}

Any help is highly appreciable. 任何帮助都非常值得赞赏。

You can send them to a dead letter queue. 您可以将它们发送到死信队列。 It's a pretty standard pattern. 这是一个非常标准的模式。

https://www.rabbitmq.com/dlx.html https://www.rabbitmq.com/dlx.html

You need something like this: 你需要这样的东西:

@Bean
RetryOperationsInterceptor interceptor() {
    return RetryInterceptorBuilder.stateless()
            .withMaxAttempts(5)
            .setRecoverer(new RepublishMessageRecoverer(amqpTemplate(), "bar", "baz"))
            .build();
}

Notice : It works only with spring-amqp 1.3+ see also the Reference 注意 :它仅适用于spring-amqp 1.3+另请参阅参考资料

If you prefer to use declarations, see this answer for an example. 如果您更喜欢使用声明,请参阅此答案以获取示例。

To route messages to the DLX , you can set defaultRequeuRejected to false (on the listener container). 要将消息路由到DLX ,可以将defaultRequeuRejected设置为false (在侦听器容器上)。 Or you can throw an AmqpRejectAndDontRequeueException to tell the container you want this message to be rejected (and not requeued). 或者您可以抛出AmqpRejectAndDontRequeueException来告诉容器您希望拒绝此消息(而不是重新排队)。

The container's default behavior is to requeue rejected messages. 容器的默认行为是重新排队被拒绝的消息。

You can use a retry interceptor with a RejectAndDontRequeueRecoverer to automatically throw the exception; 您可以使用带有RejectAndDontRequeueRecoverer的重试拦截器来自动抛出异常; or, as @Jawo99 says, you can use a republish recoverer - this has the added benefit of adding the stack trace as a header. 或者,正如@ Jawo99所说,您可以使用重新发布的恢复器 - 这具有将堆栈跟踪添加为标头的额外好处。 The DLX just routes the original message. DLX只是路由原始邮件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM