SpringBoot整合Rabbitmq之死信队列

1. 死信队列

死信:无法被消费方消费掉的消息,称为死信。如果死信一直留在队列中,会导致一直被消费,却从不消费成功。所以 rabbitmq 专门开辟了一个来存放死信的队列,叫死信队列(DLX,dead-letter-exchange

1.1. 死信从何而来

  • 消息消费方调用了 basicNack()basicReject(),并且参数都是 requeue = false,则消息会路由进死信队列
  • 消息过期,过了 TTL 存活时间,就是消费方在 TTL 时间之内没有消费,则消息会路由进死信队列
  • 队列设置了 x-max-length 最大消息数量且当前队列中的消息已经达到了这个数量,再次投递,消息将被挤掉,被挤掉的消息会路由进死信队列
  • 有一种场景需要注意下:消费者设置了自动 ACK,当重复投递次数达到了设置的最大 retry 次数之后,消息也会投递到死信队列,但是内部的原理还是调用了 basicNack()basicReject()
#开启rabbitmq的生产端重试机制,默认是false,默认重试 3 次
spring.rabbitmq.template.retry.enabled=true
#开启rabbitmq的消费端重试机制,默认是false,默认重试 3 次
spring.rabbitmq.listener.simple.retry.enabled=true
#设置重试的次数
spring.rabbitmq.listener.simple.retry.max-attempts=5

1.2. 死信流程

死信流程图

在这里插入图片描述

  • 正常业务消息被投递到正常业务的 Exchange,该 Exchange 根据路由键将消息路由到绑定的正常队列
  • 正常业务队列中的消息变成了死信消息之后,会被自动投递到该队列绑定的死信交换机上(并带上配置的路由键,如果没有指定死信消息的路由键,则默认继承该消息在正常业务时设定的路由键)
  • 死信交换机收到消息后,将消息根据路由规则路由到指定的死信队列
  • 消息到达死信队列后,可监听该死信队列,处理死信消息

死信队列并不是什么特殊的队列,只不过是绑定在死信交换机上的队列。死信交换机也不是什么特殊的交换机,只不过是用来接收死信的交换机,所以可以为任何类型(Direct、Fanout、Topic。一般来说,会为每个业务队列分配一个独有的路由 key,并对应的配置一个死信队列进行监听,也就是说,一般会为 每个重要的业务队列配置一个死信队列

2. 死信队列实现

  • SpringBoot 版本 2.0.6.RELEASE
  • Rabbitmq 版本 3.8.3

分别创建项目消息生产方,消息接收方两个项目

2.1. 消息发送方

2.1.1. 配置文件

server.port=8080

#配置rabbitmq服务器
spring.rabbitmq.host=127.0.0.1
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
#确认消息已发送到交换机
spring.rabbitmq.publisher-confirms=true
#确认消息已发送到队列
spring.rabbitmq.publisher-returns=true

2.1.2. 队列、交换机定义及绑定

@Configuration
public class DeadLetterConfig {
   

    // --------------------------正常业务队列--------------------------
    // 业务队列 A
    @Bean
    public Queue businessQueueA() {
   
        Map<String, Object> args = new HashMap<>();
        // x-dead-letter-exchange:这里声明当前业务队列绑定的死信交换机
        args.put("x-dead-letter-exchange", Constant.DEAD_LETTER_EXCHANGE);
        // x-dead-letter-routing-key:这里声明当前业务队列的死信路由 key
        args.put("x-dead-letter-routing-key", Constant.DEAD_LETTER_QUEUE_A_ROUTING_KEY);
        return new Queue(Constant.BUSINESS_QUEUE_A, true, false, false, args);
    }

    // 业务队列 B
    @Bean
    public Queue businessQueueB() {
   
        Map<String, Object> args = new HashMap<>();
        // x-dead-letter-exchange:这里声明当前队列绑定的死信交换机
        args.put("x-dead-letter-exchange", Constant.DEAD_LETTER_EXCHANGE);
        // x-dead-letter-routing-key:这里声明当前队列的死信路由 key
        args.put("x-dead-letter-routing-key", Constant.DEAD_LETTER_QUEUE_B_ROUTING_KEY);
        return new Queue(Constant.BUSINESS_QUEUE_B, true, false, false, args);
    }

    // 业务队列的交换机
    @Bean
    public TopicExchange businessTopicExchange() {
   
        return new TopicExchange(Constant.BUSINESS_EXCHANGE, true, false);
    }

    // 业务队列 A 与交换机绑定,并指定 Routing_Key
    @Bean
    public Binding businessBindingA() {
   
        return BindingBuilder.bind<
  • 8
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Spring Boot中配置死信队列(Dead Letter Queue),您可以按照以下步骤进行操作: 1. 添加RabbitMQ依赖:在您的Spring Boot项目的pom.xml文件中,添加RabbitMQ依赖。例如,使用以下Maven依赖项: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> ``` 2. 配置RabbitMQ连接信息:在application.properties或application.yml文件中,配置RabbitMQ的连接信息,例如: ```properties spring.rabbitmq.host=localhost spring.rabbitmq.port=5672 spring.rabbitmq.username=guest spring.rabbitmq.password=guest ``` 3. 创建交换机和队列:使用RabbitAdmin或通过注解方式,在您的代码中创建交换机和队列。例如,可以使用@Bean注解创建一个RabbitAdmin bean,并在其上使用@PostConstruct注解来创建交换机和队列。 ```java @Bean public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) { return new RabbitAdmin(connectionFactory); } @PostConstruct public void setupQueues() { rabbitAdmin().declareExchange(new DirectExchange("myExchange")); rabbitAdmin().declareQueue(new Queue("myQueue")); rabbitAdmin().declareBinding(new Binding("myQueue", Binding.DestinationType.QUEUE, "myExchange", "myRoutingKey", null)); } ``` 4. 配置死信队列:创建一个专用的队列来作为死信队列,并将其与原始队列绑定。您可以在队列声明时设置x-dead-letter-exchange和x-dead-letter-routing-key参数来指定死信队列的交换机和路由键。 ```java @PostConstruct public void setupQueues() { rabbitAdmin().declareExchange(new DirectExchange("myExchange")); rabbitAdmin().declareQueue(new Queue("myQueue", false, false, false, new HashMap<String, Object>() {{ put("x-dead-letter-exchange", "dlxExchange"); put("x-dead-letter-routing-key", "dlxRoutingKey");

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值