【问题标题】:Rabbitmq dead letter exchange not working resulting in infinite retriesRabbitmq 死信交换不起作用导致无限重试
【发布时间】:2020-03-16 09:53:58
【问题描述】:

我有一个制作人:

rabbitTemplate.convertAndSend(QueueConstants.PROVISIONING_EXCHANGE, QueueConstants.PROVISIONING_ROUTING_KEY, message);

还有我的配置:

@Bean
Queue organizationProvisioningQueue() {
    return QueueBuilder.durable(QueueConstants.PROVISIONING_QUEUE)
            .withArgument("x-dead-letter-exchange", "")
            .withArgument("x-dead-letter-routing-key", QueueConstants.DEAD_LETTER_QUEUE)
            .build();
}

@Bean
Queue deadLetterQueue() {
    return QueueBuilder.durable(QueueConstants.DEAD_LETTER_QUEUE).build();
}

@Bean
DirectExchange exchange() {
    return new DirectExchange(QueueConstants.PROVISIONING_EXCHANGE);
}

@Bean
Binding binding() {
    return BindingBuilder.bind(organizationProvisioningQueue()).to(exchange()).with(QueueConstants.PROVISIONING_ROUTING_KEY);
}

和我的消息处理器:

@RabbitListener(queues = QueueConstants.PROVISIONING_QUEUE)
public void process(ProvisioningMessage message) throws ProvisioningException {
    System.out.println("Processing " + message);

    throw new ProvisioningException ("Some ex " + message);
}

还有常量:

public static final String PROVISIONING_EXCHANGE = "provisioning-exchange";
public static final String PROVISIONING_ROUTING_KEY = "provisioning";
public static final String PROVISIONING_QUEUE = "provisioning-queue";

public static final String DEAD_LETTER_QUEUE = PROVISIONING_QUEUE + ".dlq";

死信队列不起作用,因为每次抛出异常后消息都会重新排队,从而导致无限循环而不是进入死信队列。

我已将队列名称更改为以 .dlq 结尾,因为有人建议它,但仍然没有成功。 我做错了什么?

【问题讨论】:

    标签: java rabbitmq spring-rabbit


    【解决方案1】:

    您需要抛出AmqpRejectAndDontRequeueException 或将侦听器容器的defaultRequeueRejected 属性设置为false。

    dlq 的名称无关紧要。

    【讨论】:

    • 第一个选项不是我想要的,因为我想在抛出错误时进行指数退避,所以只有第 5 个请求会转到 dlq,第二个我设置 spring.rabbitmq.listener.default -requeue-rejected= false 在我的 application.properties 中,但消息仍然无限重新排队。
    • 这对我来说毫无意义;一定有什么问题。但是,如果您使用重试,您可以在重试拦截器中配置RejectAndDontRequeueRecoverer,当重试用尽时它将拒绝该消息。
    【解决方案2】:

    最近我遇到了类似的问题(出现异常时消息的无限排队)。就我而言,设置此应用程序属性解决了问题:

    spring.rabbitmq.listener.simple.default-requeue-rejected=false
    

    【讨论】:

      【解决方案3】:

      从 RabbitMQ 3.8.0 开始,可以使用 RabbitMQ 中的毒物消息处理,通过使用新类型的队列:Quorum Queues。

      Quorum queue 支持处理有害消息,即导致消费者重复重新排队传递的消息(可能是由于消费者失败),使得消息永远不会被完全消费并积极确认,以便可以将其标记为被 RabbitMQ 删除。

      请注意,仲裁队列目前不支持某些功能:

      仲裁队列会跟踪不成功的传递尝试次数,并将其显示在包含在任何重新传递的消息中的“x-delivery-count”标头中。

      可以使用策略参数传递限制为队列设置传递限制。当消息返回的次数超过限制时,消息将被丢弃或死信(如果配置了 DLX)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-11-17
        • 2012-12-17
        • 2013-12-21
        • 2014-03-11
        • 1970-01-01
        • 2020-05-30
        • 1970-01-01
        • 2021-01-18
        相关资源
        最近更新 更多