Rabbitmq之消息过期设置

消息的过期时间

目前有两种方法可以设置消息的 TTL 。第一种方法是通过队列属性设置,队列中所有消息都有相同的过期时间。第二种方法是对消息本身进行单独设置,每条消息的TTL可以不同。如果两种方法一起使用,则消息的TTL以两者之间较小的那个数值为准。
对于第一种设置队列属性的方法,一旦消息过期,就会从队列中抹去,而在第二种方法中,即使消息过期,也不会马上从队列中抹去,因为每条消息是否过期是在即将投递到消费者之前判定的。


为什么这两种方法处理的方式不一样?
因为第一种方法里,队列中己过期的消息肯定在队列头部,RabbitMQ只要定期从队头开始扫描是否有过期的消息即可。而第二种方法里,每条消
息的过期时间不同,如果要删除所有过期消息势必要扫描整个队列,所以不如等到此消息即将被消费时再判定是否过期,如果过期再进行删除即可。

 

1、声明交换机

    /**
     * 1、声明交换机
     */
    @Test
    public void decalreExchange() throws Exception {

        String exchange = "hello_ttl";
        // 获取到连接
        Connection connection = ConnectionUtil.getConnection();
        // 获取通道
        Channel channel = connection.createChannel();

        // 声明exchange,指定类型为direct
        channel.exchangeDeclare(exchange, BuiltinExchangeType.DIRECT,true,false,false,new HashMap<>());
    }

 

2、这里声明了两个队列,hello_ttl_c1给队列设置了消息过期时间,hello_ttl_c2没有设置。

    /**
     * 2、声明队列并绑定到交换机
     */
    @Test
    public void decalreQueueAndBind() throws Exception {

        String exchange = "hello_ttl";
        // 获取到连接
        Connection connection = ConnectionUtil.getConnection();
        // 获取通道
        Channel channel = connection.createChannel();

        //将队列hello_ttl_c1 绑定到交换机hello_ttl上
        String queueName1 = "hello_ttl_c1";
        Map<String, Object> argss = new HashMap<String , Object>();
        argss.put("x-message-ttl" , 30*1000);//设置队列里消息的ttl的时间30s
        // 声明队列
        channel.queueDeclare(queueName1, true, false, false, argss);
        // 绑定队列到交换机
        channel.queueBind(queueName1, exchange, "aaa");

        //队列hello_ttl_c2  这个是为了测试通过发送时设置ttl
        String queueName2 = "hello_ttl_c2";
        // 声明队列
        channel.queueDeclare(queueName2, true, false, false, null);
        // 绑定队列到交换机
        channel.queueBind(queueName2, exchange, "bbb");

    }

可以看出队列上的TTL属性,D是声明队列durable设置为true,表示队列是持久化的。

44eff720ee09cbc8ca00ada710e8108d0f2.jpg

 

3、测试设置过期时间的队列

    /**
     * 测试队列设置的ttl
     * @throws Exception
     */
    @Test
    public void sendMessage1() throws Exception {
        String exchange = "hello_ttl";
        // 获取到连接
        Connection connection = ConnectionUtil.getConnection();
        // 获取通道
        Channel channel = connection.createChannel();
        // 消息内容
        String message = "Less is more";
        channel.basicPublish(exchange, "aaa", null, message.getBytes());
        log.debug("Producer send message:{}",message);
        channel.close();
        connection.close();
    }

30s 后,可以看到该消息被删除

9bcff5c1486efdd556ec67fda4fe962eb79.jpg

4、测试发送时设置ttl

    /**
     * 测试消息发送时设置ttl
     * @throws Exception
     */
    @Test
    public void sendMessage2() throws Exception {
        String exchange = "hello_ttl";
        // 获取到连接
        Connection connection = ConnectionUtil.getConnection();
        // 获取通道
        Channel channel = connection.createChannel();
        // 消息内容
        String message = "Less is more";
        AMQP.BasicProperties.Builder builder = new AMQP.BasicProperties.Builder();
        builder.deliveryMode(2); //DeliveryMode等于2就说明这个消息是persistent的。1是默认,不是持久的。
        builder.expiration("30000");// 设置TTL=30000ms
        AMQP.BasicProperties properties = builder. build() ;
        channel.basicPublish(exchange, "bbb", properties, message.getBytes());
        log.debug("Producer send message:{}",message);
        channel.close();
        connection.close();
    }

大约30s后,消息也被删除

0e010779b6e59136ac93a0b0727b6841096.jpg

详细源码地址

https://github.com/suzhe2018/rabbitmq-item

77183bb4545894cda09f81c85f1db6ca1bf.jpg

 

转载于:https://my.oschina.net/suzheworld/blog/3003095

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值