RabbitMQ高级-死信队列

概述

DLX,全称为Dead-Letter-Exchange , 可以称之为死信交换机,也有人称之为死信邮箱。当消息在一个队列中变成死信(dead message)之后,它能被重新发送到另一个交换机中,这个交换机就是DLX ,绑定DLX的队列就称之为死信队列。
消息变成死信,可能是由于以下的原因:

  • 消息被拒绝
  • 消息过期
  • 队列达到最大长度

DLX也是一个正常的交换机,和一般的交换机没有区别,它能在任何的队列上被指定,实际上就是设置某一个队列的属性。当这个队列中存在死信时,Rabbitmq就会自动地将这个消息重新发布到设置的DLX上去,进而被路由到另一个队列,即死信队列。
要想使用死信队列,只需要在定义队列的时候设置队列参数 x-dead-letter-exchange 指定交换机即可。

在这里插入图片描述
在这里插入图片描述

1、消息过期进入死信队列

1、创建交换机和队列,并且绑定

package com.sky.config;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * @author 尹稳健~
 * @version 1.0
 */
@Configuration
public class TTLDirectRabbitMQConfig {

    // 声明注册交换机
    @Bean
    public DirectExchange ttlDirectExchange(){
        return new DirectExchange("ttl_direct_exchange");
    }

    // 声明队列
    @Bean
    public Queue ttlQueueDirect(){
        Map<String,Object> args = new HashMap<>();
        // 设置过期时间
        args.put("x-message-ttl",5000);
        // 设置死信队列
        args.put("x-dead-letter-exchange","dead_direct_exchange");
        // 设置 路由key
        args.put("x-dead-letter-routing-key","dead");
        return new Queue("ttl.direct.queue",true,false,false,args);
    }

    // 交换机和队列绑定
    @Bean
    public Binding ttlBindingDirect(){
        return BindingBuilder.bind(ttlQueueDirect()).to(ttlDirectExchange()).with("ttl");
    }
}

2、发送消息

public void makeOrderTTL(String userId, String productId, int num) {
    // 1:根据商品id查询库存是否充足

    //2:保存订单
    String orderId = UUID.randomUUID().toString();
    System.out.println("订单生成成功"+orderId);
    String exchangeName = "ttl_direct_exchange";
    String routeKey = "ttl";
    rabbitTemplate.convertAndSend(exchangeName,routeKey,orderId);

}

3、测试

刚刚发送消息时:
在这里插入图片描述

消息过期后:
在这里插入图片描述

小结

消息过期后转入死信交换机,然后通过死信交换机发送到死信队列中,其实死信交换机和其他的交换机没啥区别,也只是一个普普通通的交换机,不要把它想得很复杂,他只是一个回收站罢了。

  • x-dead-letter-exchange 设置死信交换机
  • x-dead-letter-routing-key 设置死信队列路由key
  • x-message-ttl 设置过期时间

2、消息队列达到最大数,其他的信息进入死信队列

1、创建交换机和队列,绑定

package com.sky.config;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * @author 尹稳健~
 * @version 1.0
 */
@Configuration
public class TTLDirectRabbitMQConfig {

    // 声明注册交换机
    @Bean
    public DirectExchange ttlDirectExchange(){
        return new DirectExchange("ttl_direct_exchange");
    }
    
    // 声明队列
    @Bean
    public Queue maxQueueDirect(){
        Map<String,Object> args = new HashMap<>();
        // 设置过期时间
        //args.put("x-message-ttl",5000);
        // 设置队列最大数
        args.put("x-max-length",3);
        // 设置死信队列
        args.put("x-dead-letter-exchange","dead_direct_exchange");
        // 设置 路由key
        args.put("x-dead-letter-routing-key","dead");
        return new Queue("max.direct.queue",true,false,false,args);
    }

    // 交换机和队列绑定
    @Bean
    public Binding maxBindingDirect(){
        return BindingBuilder.bind(maxQueueDirect()).to(ttlDirectExchange()).with("max");
    }
}

2、发送消息

public void makeOrderMax(String userId, String productId, int num) {
    // 1:根据商品id查询库存是否充足
    //2:保存订单
    String orderId = UUID.randomUUID().toString();
    System.out.println("订单生成成功"+orderId);
    String exchangeName = "ttl_direct_exchange";
    String routeKey = "max";
    rabbitTemplate.convertAndSend(exchangeName,routeKey,orderId);

}

3、测试

因为队列最大消息数设置为3条,我们测试一下队列达到最大数时,哪些消息会进入到死信队列中。

在这里插入图片描述

在这里插入图片描述

小结

通过多次发送消息发现:当队列达到最大数时,继续发送消息,先前发送的消息会被丢弃到队列中,这就很像数据结构中的队列了,先进先出。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

毕竟尹稳健

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值