rabbitmq的高级知识-ttl与死信队列

TTL

TTL(Time To Live)是RabbitMQ中用于设置消息或队列存活时间 的机制。通过TTL可以控制消息或队列在未被消费时的自动过期时间,避免无效消息堆积。

队列级别的TTL

队列级别的TTL会对队列中所有消息生效通过x-message-ttl 参数设置,在创建队列时,就需要绑定ttl参数

示例代码如下:

创建交换机与队列

java 复制代码
package com.lx.producer.config;

import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

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


@Configuration
public class RabbitMqConfiguration {


    //创建一个direct类型的交换机
    @Bean
    public DirectExchange directExchangeExchange(){
        //第一个参数是交换机的名字,第二个是是否持久化,第三个是是否自动删除
        return new DirectExchange("ttl_direct_exchange",true,false);
    }


    //创建队列

    @Bean
    public Queue ttlQueue(){
        Map<String,Object> args =new HashMap<>();
        args.put("x-message-ttl",5000);
        return new Queue("sms.direct.queue",true,false,false,args);
    }






    //队列进行绑定关系
    @Bean
    public Binding smsBinding(){
        return BindingBuilder.bind(ttlQueue()).to(directExchangeExchange()).with("sms");

    }

生产者业务代码(发送信息)

java 复制代码
package com.lx.producer.service;

import jakarta.annotation.Resource;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;

import java.sql.SQLOutput;
import java.util.UUID;


@Service
public class OrderService {

    @Resource
    RabbitTemplate rabbitTemplate;


    public void makeOrder(String userId,String productId,Integer numbers){
        String orderId= UUID.randomUUID().toString();
        System.out.println("订单生产成功:"+orderId);

        //通过MQ完成消息的发送

        String exchangeName="ttl_direct_exchange";
        String routingKey1="sms";
      
        rabbitTemplate.convertAndSend(exchangeName,routingKey1,orderId);
     

    }
}

生产者向队列发送信息后,如果此队列的消息没在ttl时间之内被消费掉,那么此队列的消息就会自动丢失

消息级别的ttl

与队列级别不同的是,消息级别的ttl是给每个消息设置ttl,而不是像刚刚那样给一个队列中的所有的消息设置ttl,如果两者冲突的话(队列中有ttl,消息中也有ttl),那就按最短的ttl来

示例代码如下

java 复制代码
package com.lx.producer.config;

import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

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


@Configuration
public class RabbitMqConfiguration {


    //创建一个direct类型的交换机
    @Bean
    public DirectExchange directExchangeExchange(){
        //第一个参数是交换机的名字,第二个是是否持久化,第三个是是否自动删除
        return new DirectExchange("ttl_message_direct_exchange",true,false);
    }


    //创建三个队列

    @Bean
    public Queue ttlQueue(){
//        Map<String,Object> args =new HashMap<>();
//        args.put("x-message-ttl",5000);
        return new Queue("sms.direct.queue",true);
    }






    //三个队列分别进行绑定关系
    @Bean
    public Binding smsBinding(){
        return BindingBuilder.bind(ttlQueue()).to(directExchangeExchange()).with("sms");

    }

}

生产者业务发送信息代码

java 复制代码
package com.lx.producer.service;

import jakarta.annotation.Resource;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;

import java.sql.SQLOutput;
import java.util.UUID;


@Service
public class OrderService {

    @Resource
    RabbitTemplate rabbitTemplate;


    public void makeOrder(String userId,String productId,Integer numbers){
        String orderId= UUID.randomUUID().toString();
        System.out.println("订单生产成功:"+orderId);

        //通过MQ完成消息的发送

        String exchangeName="ttl_message_direct_exchange";
        String routingKey1="sms";

        //给消息设置ttl
        MessagePostProcessor messagePostProcessor=new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                message.getMessageProperties().setExpiration("5000");
                message.getMessageProperties().setContentEncoding("UTF-8");
                return message;
            }
        };


       
        rabbitTemplate.convertAndSend(exchangeName,routingKey1,orderId,messagePostProcessor);
    

    }
}

死信队列

死信队列(Dead Letter Queue, DLQ)是RabbitMQ中用于处理无法被正常消费的消息的机制。当消息满足特定条件时,会被重新路由到死信队列,便于后续处理或分析。

应用场景
消息被消费者拒绝 (basic.reject或basic.nack)且设置requeue参数为false。 消息在队列中存活时间超过设定的TTL(Time-To-Live)。 队列达到最大长度限制,无法再容纳新消息。

示例代码如下(超过ttl为例):

创建交换机与队列

java 复制代码
package com.lx.producer.config;

import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

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


@Configuration
public class RabbitMqConfiguration {


    //创建一个direct类型的交换机
    @Bean
    public DirectExchange directExchangeExchange(){
        //第一个参数是交换机的名字,第二个是是否持久化,第三个是是否自动删除
        return new DirectExchange("ttl_message_direct_exchange",true,false);
    }

   //创建一个死信交换机
    @Bean
    public DirectExchange deadDirectExchange(){
        //第一个参数是交换机的名字,第二个是是否持久化,第三个是是否自动删除
        return new DirectExchange("dead_direct_exchange",true,false);
    }

    //创建三个队列

    @Bean
    public Queue ttlQueue(){
        Map<String,Object> args =new HashMap<>();
        args.put("x-message-ttl",5000);
        args.put("x-dead-letter-exchange","dead_direct_exchange");
        args.put("x-dead-letter-routing-key","dead");
        return new Queue("sms.direct.queue",true,false,false,args);
    }

    //死信队列
    @Bean
    public Queue deadQueue(){
        return new Queue("dead.direct.queue",true);
    }






    //三个队列分别进行绑定关系
    @Bean
    public Binding smsBinding(){
        return BindingBuilder.bind(ttlQueue()).to(directExchangeExchange()).with("sms");

    }

    @Bean
    public Binding deadBinding(){
        return BindingBuilder.bind(deadQueue()).to(deadDirectExchange()).with("dead");

    }

}

生产者业务代码与之前的一样,这样如果我们发送信息到队列的时候,如果队列中的信息没有及时被消费掉的话,那这个队列就会把过期消息发到死信交换机,从而发送到死信对列中。

相关推荐
weisian15112 小时前
Java并发编程--45-分布式一致性协议入门:Raft、Paxos与ZAB的核心思想
java·分布式·raft·paxos·zab
juniperhan14 小时前
Flink 系列第17篇:Flink Table&SQL 核心概念、原理与实战详解
大数据·数据仓库·分布式·sql·flink
卢傢蕊16 小时前
FastDFS 分布式存储
分布式·fastdfs
菜鸟小码17 小时前
Hadoop大数据时代的底座和基石
大数据·hadoop·分布式
珠海西格电力18 小时前
零碳园区管理系统如何守护能源与数据安全?
大数据·人工智能·分布式·架构·能源
weisian15119 小时前
Java并发编程--44-分布式限流:令牌桶与漏桶算法在网关层的落地
java·分布式·令牌桶算法·漏桶算法·固定窗口算法·滑动窗口算法
想你依然心痛1 天前
HarmonyOS 6(API 23)分布式实战:基于悬浮导航与沉浸光感的“光影协创“跨设备白板系统
分布式·wpf·harmonyos·悬浮导航·沉浸光感
立莹Sir1 天前
商品中台架构设计与技术落地实践——基于Spring Cloud微服务体系的完整解决方案
分布式·后端·spring cloud·docker·容器·架构·kubernetes
人道领域1 天前
【Redis实战篇】初步基于Redis实现的分布式锁---基于黑马点评
java·数据库·redis·分布式·缓存
buhuimaren_1 天前
FastDFS分布式存储
分布式