RabbitMQ详解(五):过期时间TTL、死信队列、磁盘监控

这篇具有很好参考价值的文章主要介绍了RabbitMQ详解(五):过期时间TTL、死信队列、磁盘监控。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

过期时间TTL(Time To Live)

过期时间TTL表示可以对消息设置预期的时间,在这个时间内都可以被消费者接收获取;过了之后消息将自动被删除。

目前有两种方法可以设置

  • 第一种方法是通过队列属性设置,队列中所有消息都有相同的TTL。
  • 第二种方法是对消息进行单独设置,每条消息TTL可以不同。

当同时指定了 queue 和 message 的 TTL 值,则两者中较小的那个才会起作用。

设置队列TTL

  • 过期时间参数(x-message-ttl 为固定值)

    x-message-ttl,中间件,java-rabbitmq,rabbitmq,java

  • 在springboot_rabbitmq_producer 代码的基础上新增以下配置文件

    参数 x-message-ttl 的值 必须是非负 32 位整数 (0 <= n <= 2^32-1) ,以毫秒为单位表示 TTL 的值。这样,值 5000 表示存在于 队列 中的当前 消息 将最多只存活 5 秒钟。

    package com.cn.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;
    
    @Configuration
    public class TTLDirectRabbitmqConfig {
    
        //1.声明交换机
        @Bean
        public DirectExchange ttldirectExchange(){
         return new DirectExchange("ttl-direct-exchange", true, false);
        }
    
        //2.声明队列
        @Bean
        public Queue directTTLQueue(){
            //设置过期时间,以毫秒为单位
            HashMap<String, Object> map = new HashMap<>();
            map.put("x-message-ttl", 5000);
            return new Queue("ttl.direct.queue", true, false, false, map);
        }
    
        //3.交换机和队列进行绑定
        @Bean
        public Binding directTTLBinding(){
            return BindingBuilder.bind(directTTLQueue()).to(ttldirectExchange()).with("ttl");
        }
    }
    
  • 生产者代码中新增以下方法

       public void createOrderDirectTTL(String useerId, String productId, int num){
            String orderId = UUID.randomUUID().toString();
            String exchangeName  = "ttl-direct-exchange";
            String routeKey  = "ttl";
            rabbitTemplate.convertAndSend(exchangeName, routeKey, orderId);
        }
    
  • 测试类

     @Test
        void testOrderDirectTTL() {
            orderService.createOrderDirectTTL("1","1",555);
        }
    
  • 启动测试,查看图形化管理界面,会看到队列上有DDL标识

    x-message-ttl,中间件,java-rabbitmq,rabbitmq,java

    静等5秒之后会看到消息自动消失

    x-message-ttl,中间件,java-rabbitmq,rabbitmq,java

设置消息TTL

  • 在上面代码的基础上修改

     @Bean
        public Queue directTTLQueue2(){
            return new Queue("ttl2.direct.queue", true);
        }
    
       @Bean
        public Binding directTTL2Binding(){
            return BindingBuilder.bind(directTTLQueue2()).to(ttldirectExchange()).with("ttl2");
        }
    
  • 生产者代码

    public void createOrderDirectTTL2(String useerId, String productId, int num){
            String orderId = UUID.randomUUID().toString();
            String exchangeName  = "ttl-direct-exchange";
            String routeKey  = "ttl2";
            // 对消息设置过期时间
            MessagePostProcessor messagePostProcessor = new MessagePostProcessor() {
                @Override
                public Message postProcessMessage(Message message) throws AmqpException {
                    message.getMessageProperties().setExpiration("5000");
                    return message;
                }
            };
            rabbitTemplate.convertAndSend(exchangeName, routeKey, orderId, messagePostProcessor);
        }
    

    expiration 字段以微秒为单位表示 TTL 值。且与 x-message-ttl 具有相同的约束条件。因为 expiration 字段必须为字符串类型,broker 将只会接受以字符串形式表达的数字。

  • 测试代码

     @Test
        void testOrderDirectTTL2() {
            orderService.createOrderDirectTTL2("1","1",666);
        }
    
  • 启动测试,查看图形化管理界面,会看到队列上没有DDL标识,但是我们静等5秒钟后,队列中的消息也会自动消失

    x-message-ttl,中间件,java-rabbitmq,rabbitmq,java

    x-message-ttl,中间件,java-rabbitmq,rabbitmq,java

死信队列

DLX,全称为Dead-Letter-Exchange , 可以称之为死信交换机,也有人称之为死信邮箱。

当消息在一个队列中变成死信(dead message)之后,它能被重新发送到另一个交换机中,这个交换机就是DLX ,绑定DLX的队列就称之为死信队列。

消息变成死信,可能是由于以下的原因:

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

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

  • 添加死信队列和交换机绑定关系

    package com.cn.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;
    
    /**
     * 死信队列
     */
    @Configuration
    public class DeadDirectRabbitmqConfig {
    
        //1.声明交换机
        @Bean
        public DirectExchange deadDirectExchange(){
         return new DirectExchange("dead-direct-exchange", true, false);
        }
    
        //2.声明队列
        @Bean
        public Queue directDeadQueue(){
            return new Queue("dead.direct.queue", true);
        }
    
        //3.交换机和队列进行绑定
        @Bean
        public Binding directDeadBinding(){
            return BindingBuilder.bind(directDeadQueue()).to(deadDirectExchange()).with("dead");
        }
    }
    
  • 修改TTLDirectRabbitmqConfig配置

      //2.声明队列
        @Bean
        public Queue directTTLQueue(){
            //设置过期时间
            HashMap<String, Object> map = new HashMap<>();
            map.put("x-message-ttl", 5000); //过期时间
            map.put("x-dead-letter-exchange", "dead-direct-exchange"); //死信队列
            map.put("x-dead-letter-routing-key", "dead"); // direct模式需要配置routing-key
            return new Queue("ttl.direct.queue", true, false, false, map);
        }
    
  • 启动测试(需要先删除ttl.direct.queue)

    x-message-ttl,中间件,java-rabbitmq,rabbitmq,java

  • 过期后就会被投递到之前配置的死信队列中

    x-message-ttl,中间件,java-rabbitmq,rabbitmq,java

内存磁盘的监控

内存警告

当内存使用超过配置的阈值或者磁盘空间剩余空间对于配置的阈值时,RabbitMQ会暂时阻塞客户端的连接,并且停止接收从客户端发来的消息,以此避免服务器的崩溃,客户端与服务端的心态检测机制也会失效。

内存的最大极限为0.4 假设电脑是4G,那么内存的最大阈值就是1.6G

内存控制

参考帮助文档:https://www.rabbitmq.com/configure.html 当出现警告的时候,可以通过配置去修改和调整

  • 命令

    //命令设置比例
    rabbitmqctl set_vm_memory_high_watermark <fraction>
    //命令设置大小
    rabbitmqctl set_vm_memory_high_watermark absolute 50MB
    

    ​ fraction/value 为内存阈值。默认情况是:0.4/2GB,代表的含义是:当RabbitMQ的内存超过40%时,就会产生警告并且阻塞所有生产者的连接。通过此命令修改阈值在Broker重启以后将会失效,通过修改配置文件方式设置的阈值则不会随着重启而消失,但修改了配置文件一样要重启broker才会生效。

  • 测试案例

    [root@hecs-66166 ~]# rabbitmqctl set_vm_memory_high_watermark absolute 50MB
    Setting memory threshold on rabbit@hecs-66166 to 50MB bytes ...
    

    x-message-ttl,中间件,java-rabbitmq,rabbitmq,java

    [root@hecs-66166 ~]# rabbitmqctl set_vm_memory_high_watermark 0.4
    Setting memory threshold on rabbit@hecs-66166 to 0.4 ...
    

    x-message-ttl,中间件,java-rabbitmq,rabbitmq,java

内存换页

在某个Broker节点及内存阻塞生产者之前,它会尝试将队列中的消息换页到磁盘以释放内存空间,持久化和非持久化的消息都会写入磁盘中,其中持久化的消息本身就在磁盘中有一个副本,所以在转移的过程中持久化的消息会先从内存中清除掉。

默认情况下,内存到达的阈值是50%时就会换页处理。

也就是说,在默认情况下该内存的阈值是0.4的情况下,当内存超过0.4*0.5=0.2时,会进行换页动作。

比如有1000MB内存,当内存的使用率达到了400MB,已经达到了极限,但是因为配置的换页内存0.5,这个时候会在达到极限400mb之前,会把内存中的200MB进行转移到磁盘中。从而达到稳健的运行。

  • 可以通过设置 vm_memory_high_watermark_paging_ratio 来进行调整

    vm_memory_high_watermark.relative = 0.4vm_memory_high_watermark_paging_ratio = 0.7(设置小于1的值)
    

为什么设置小于1,以为你如果你设置为1的阈值。内存都已经达到了极限了。你在去换页意义不是很大了。

磁盘预警

当磁盘的剩余空间低于确定的阈值时,RabbitMQ同样会阻塞生产者,这样可以避免因非持久化的消息持续换页而耗尽磁盘空间导致服务器崩溃。

默认情况下:磁盘预警为50MB的时候会进行预警。表示当前磁盘空间第50MB的时候会阻塞生产者并且停止内存消息换页到磁盘的过程。
这个阈值可以减小,但是不能完全的消除因磁盘耗尽而导致崩溃的可能性。比如在两次磁盘空间的检查空隙内,第一次检查是:60MB ,第二检查可能就是1MB,就会出现警告。

  • 命令

    rabbitmqctl set_disk_free_limit  <disk_limit>
    rabbitmqctl set_disk_free_limit memory_limit  <fraction>
    
    disk_limit:固定单位 KB MB GB
    fraction :是相对阈值,建议范围在:1.0~2.0之间。(相对于内存)
    
  • 测试案例

    [root@hecs-66166 ~]# rabbitmqctl set_disk_free_limit 40GB
    Setting disk free limit on rabbit@hecs-66166 to 40GB bytes ...
    

    x-message-ttl,中间件,java-rabbitmq,rabbitmq,java

    [root@hecs-66166 ~]# rabbitmqctl set_disk_free_limit 50MB
    Setting disk free limit on rabbit@hecs-66166 to 50MB bytes ...
    

    x-message-ttl,中间件,java-rabbitmq,rabbitmq,java文章来源地址https://www.toymoban.com/news/detail-763466.html

到了这里,关于RabbitMQ详解(五):过期时间TTL、死信队列、磁盘监控的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【110期】面试官:说说 RabbitMQ 消费端限流、TTL、死信队列?

    * entire channel rather than each consumer * @throws java.io.IOException if an error is encountered */ void basicQos(int prefetchSize, int prefetchCount, boolean global) throws IOException; prefetchSize:0,单条消息大小限制,0代表不限制 prefetchCount:一次性消费的消息数量。会告诉 RabbitMQ 不要同时给一个

    2024年04月27日
    浏览(31)
  • RabbitMQ 过期时间(TTL)

    TTL,Time to Live的简称,即过期时间,RabbitMQ可以对消息和队列设置TTL。        RabbitMQ支持设置队列的过期时间和消息的过期时间。如果设置队列的过期时间则队列中所有的消息都有相同的过期时间。如果设置消息的过期时间则每条消息的过期时间则可以不同。如两个方法一

    2024年02月14日
    浏览(34)
  • 【RabbitMQ】 RabbitMQ 消息的延迟 —— 深入探索 RabbitMQ 的死信交换机,消息的 TTL 以及延迟队列

    消息队列是现代分布式应用中的关键组件,用于实现异步通信、解耦系统组件以及处理高并发请求。消息队列可以用于各种应用场景,包括任务调度、事件通知、日志处理等。在消息队列的应用中,有时需要实现消息的延迟处理、处理未能成功消费的消息等功能。 本文将介绍

    2024年02月05日
    浏览(79)
  • 如何保证消息的可靠性+延迟队列(TTL+死信队列+延迟队列)

    目录 1.如何保证消息的可靠性 1.1.消息的可靠投递 confirm机制 return机制 1.2.如何保证消息在队列中不丢失 1.3.确保消息能可靠的被消费掉 2.延迟队列 2.1.TTL 2.2.死信队列 2.3.延迟队列 3.如何防止消费者重复消费消息 在生产环境中由于一些不明原因,导致 rabbitmq 重启,在 RabbitMQ 重

    2024年02月15日
    浏览(59)
  • 【RabbitMQ】RabbitMQ高级:死信队列和延迟队列

    在电商平台下单,订单创建成功,等待支付,一般会给30分钟的时间,开始倒计时。如果在这段时间内用户没有支付,则默认订单取消。 该如何实现? 定期轮询(数据库等) 用户下单成功,将订单信息放入数据库,同时将支付状态放入数据库,用户付款更改数据库状态。定

    2024年01月17日
    浏览(59)
  • RabbitMQ - 死信队列,延时队列

    死信队列: DLX 全称(Dead-Letter-Exchange),称之为死信交换器,当消息变成一个死信之后,如果这个消息所在的队列存在 x-dead-letter-exchange 参数,那么它会被发送到x-dead-letter-exchange对应值的交换器上,这个交换器就称之为死信交换器,与这个死信交换器绑定的队列就是死信队列

    2024年02月09日
    浏览(49)
  • RabbitMQ-死信交换机和死信队列

    DLX: Dead-Letter-Exchange 死信交换器,死信邮箱 当消息成为Dead message后,可以被重新发送到另一个交换机,这个交换机就是DLX。 如下图所示: 其实死信队列就是一个普通的交换机,有些队列的消息成为死信后,(比如过期了或者队列满了)这些死信一般情况下是会被 RabbitMQ 清理

    2024年02月08日
    浏览(47)
  • RabbitMQ延迟队列,死信队列配置

    延迟和死信队列的配置 延迟队列有效期一分钟,后进入死信队列,如果异常就进入异常队列 异常队列配置类

    2024年02月14日
    浏览(53)
  • Rabbitmq死信队列及延时队列实现

    问题:什么是延迟队列 我们常说的延迟队列是指消息进入队列后不会被立即消费,只有达到指定时间后才能被消费。 但RabbitMq中并 没有提供延迟队列功能 。那么RabbitMQ如何实现延迟队列 通过:死信队列 + RabbitMQ的TTL特性实现。 实现原理 给一个普通带有过期功能的队列绑定一

    2024年02月15日
    浏览(48)
  • 【RabbitMQ笔记10】消息队列RabbitMQ之死信队列的介绍

    这篇文章,主要介绍消息队列RabbitMQ之死信队列。 目录 一、RabbitMQ死信队列 1.1、什么是死信队列 1.2、设置过期时间TTL 1.3、配置死信交换机和死信队列(代码配置) (1)设置队列过期时间 (2)设置单条消息过期时间 (3)队列设置死信交换机 (4)配置的基本思路 1.4、配置

    2024年02月16日
    浏览(82)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包