MQ高级-TTL

请添加图片描述
个人名片:

博主酒徒ᝰ.
个人简介沉醉在酒中,借着一股酒劲,去拼搏一个未来。
本篇励志三人行,必有我师焉。

请添加图片描述
本项目基于B站黑马程序员Java《SpringCloud微服务技术栈》,SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式

【SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 点击观看

三、死信交换机

2. TTL

一个队列中的消息如果超时未消费,则会变为死信,超时分为两种情况:

  • 消息所在的队列设置了超时时间
  • 消息本身设置了超时时间
  1. 接收超时死信的死信交换机

在consumer服务的SpringRabbitListener中,定义一个新的消费者,并且声明 死信交换机、死信队列:

@RabbitListener(bindings = @QueueBinding(
        value = @Queue(name = "dl.queue", durable = "true"),
        exchange = @Exchange(name = "dl.direct", durable = "true", autoDelete = "false"),
        key = "dl"
))
public void listenDlQueue(String msg) {
    
    
    log.info("接收到dl.queue死信消息:{}", msg);
}
  1. 声明一个队列,并且指定TTL

要给ttl队列设置超时时间,需要在声明ttl队列时配置x-message-ttl(超时时间)属性。同时绑定死信交换机。并声明ttl交换机与ttl队列绑定:

只有在队列设置了死信交换机和死信路由键时,消息才会进入死信交换机。如果队列没有设置死信交换机或死信路由键,消息将会被直接丢弃。

@Bean
public Queue ttlQueue() {
    
    
    return QueueBuilder
            .durable("ttl.queue")
            .ttl(10000)
            .deadLetterExchange("dl.direct")
            .build();
}

@Bean
public DirectExchange ttlExchange(){
    
    
    return new DirectExchange("ttl.direct");
}

@Bean
public Binding ttlBinding(){
    
    
    return BindingBuilder.bind(ttlQueue()).to(ttlExchange()).with("ttl");
}

发送消息,但是不要指定TTL:

@Test
public void testTtl() {
    
    
    CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
    rabbitTemplate.convertAndSend("ttl.direct","ttl", "hello, ttl", correlationData);
    log.info("消息发送成功:hell ttl");
}

发送消息的日志:

在这里插入图片描述

查看下接收消息的日志:
在这里插入图片描述

因为队列的TTL值是10000ms,也就是10秒。可以看到消息发送与接收之间的时差刚好是10秒。

  1. 发送消息时,设定TTL

在发送消息时,也可以指定TTL,在消息内设置有效时间:

@Test
public void testTtl() {
    
    
    //创建消息,并设置过期时间
    Message message = MessageBuilder
            .withBody("hello, ttl".getBytes(StandardCharsets.UTF_8))
            .setExpiration("5000")
            .build();
    CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
    rabbitTemplate.convertAndSend("ttl.direct","ttl", message, correlationData);
    log.info("消息发送成功:hell ttl");
}

查看发送消息日志:
在这里插入图片描述

接收消息日志:
在这里插入图片描述

这次,发送与接收的延迟只有5秒。说明当队列、消息都设置了TTL时,任意一个到期就会成为死信。

总结

消息超时的两种方式是?

  • 给队列设置ttl属性,进入队列后超过ttl时间的消息变为死信
  • 给消息设置ttl属性,队列接收到消息超过ttl时间后变为死信

如何实现发送一个消息20秒后消费者才收到消息?

  • 给消息的目标队列指定死信交换机
  • 将消费者监听的队列绑定到死信交换机
  • 发送消息时给消息或队列设置超时时间为20秒

猜你喜欢

转载自blog.csdn.net/m0_65144570/article/details/133150868
TTL
MQ