RabbitMQ-----------死信队列和延迟队列

目录

      • 死信队列
      • 延迟队列

死信队列

一、首先知道什么是死信消息
1.消息被决绝或者未签收,并且没有重新返回到队列中(requeue=false)
2.消息过期
3.队列达到最大长度
死信消息就会出现在死信队列里
二、消费端配置
与之前不同主要声明queue时arguments参数,x-dead-letter-exchange(交换机),x-dead-letter-routing-key(路由key)通过哪个交换机转到哪个路由key上
/**
     * 死信队列 交换机标识符
     */
    private static final String DEAD_LETTER_QUEUE_KEY = "x-dead-letter-exchange";
    /**
     * 死信队列交换机绑定键标识符
     */
    private static final String DEAD_LETTER_ROUTING_KEY = "x-dead-letter-routing-key";
@RabbitHandler
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "order_queue3", durable = "true"
                    , arguments = {@Argument(name = DEAD_LETTER_QUEUE_KEY, value = "order_exchange"), @Argument(name = DEAD_LETTER_ROUTING_KEY, value = "DL_KEY")}),
            exchange = @Exchange(
                    value = "order_exchange",
                    ignoreDeclarationExceptions = "true",
                    type = ExchangeTypes.DIRECT,
                    durable = "true"
            ),
            key = {"order_routing"}
    ))
    public void listen(Message message, Channel channel) throws IOException {
        LocalDateTime now = LocalDateTime.now();
        log.info("order_queue,接收时间=[{}],order=[{}]", now.toString(), message);
        try {
            //todo 处理
            sum();
            rateLimiter.acquire();
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
            log.error("error", e);
        }
    }
    监听死信队列
    @RabbitHandler
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "order_dead_queue", durable = "true"),
            exchange = @Exchange(
                    value = "order_exchange",
                    ignoreDeclarationExceptions = "true",
                    type = ExchangeTypes.DIRECT,
                    durable = "true"
            ),
            key = {"DL_KEY"}
    ))
    public void deadQueuelisten(Message message, Channel channel) throws IOException {
        LocalDateTime now = LocalDateTime.now();
        log.info("死信队列: order_dead_queue,接收时间=[{}],order=[{}]", now.toString(), message);
        try {
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
            log.error("error", e);
        }
    }
三、生产者
加了MessagePostProcessor参数,声明消息有效时间
  //全局唯一id
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
        MessagePostProcessor messagePostProcessor = message -> {
            MessageProperties messageProperties = message.getMessageProperties();
//            设置编码
            messageProperties.setContentEncoding("utf-8");
//            设置过期时间2*1000毫秒(最终过期时间取x-message-ttl和messageProperties.setExpiration的最小值
            messageProperties.setExpiration("2000");
            return message;
        };
        rabbitTemplate.convertAndSend(ORDER_EXCHANG, ORDER_ROUTING, content, messagePostProcessor, correlationData);

延迟队列

RabbitMQ并没有延迟队列,但是死信队列和消息设置过期时间可以达到延迟队列的目的。
例如下单之后30分钟之内未支付的取消订单,那么设置下单支付消息30分过期,进入进入死信队列,一旦进入死信队列就取消订单

其实上面的死信队列已经起到了延迟队列的作用,2秒内如果消费不了就会转投到死信队列里

你可能感兴趣的:(RabbitMQ)