微服务框架
【SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】
服务异步通讯
文章目录
- 微服务框架
- 服务异步通讯
- 51 死信交换机
- 51.2 TTL
- 51.2.1 TTL
- 51.2.2 总结
51 死信交换机
51.2 TTL
51.2.1 TTL
TTL,也就是Time-To-Live。【存活时间】
如果一个队列中的消息TTL结束仍未消费,则会变为死信,ttl超时分为两种情况:
- 消息所在的队列设置了存活时间
- 消息本身设置了存活时间
【举个栗子】
生产者 → 交换机 → 队列 → 死信交换机 → 死信队列
现在有了一个消息
这个消息它 自己设置了 TTL ,为 5000ms,当消息发出,到达 ttl.queue 队列的那一刻,
它就会开始 倒计时,倒计时结束,
这个消息就变成 了死信
从而 投递到死信交换机,最终到达 死信队列
这个时候如果恰好 有一个消费者 在监听着 死信队列
那它肯定就能收到这个消息了
从整个流程看来,就变成了 生产者发送了 一个消息,5 s 中后消费者才拿到【就实现了一个延迟投递的效果】
当然除了给 消息设置TTL ,也可以给队列设置TTL,
10 s。如果消息和队列 都有自己的TTL,这个时候就会依较小 的。
【试试】
我们声明一组死信交换机和队列,基于注解方式:
要给队列设置超时时间,需要在声明队列时配置x-message-ttl属性:
【实现】
修改监听类
@RabbitListener(bindings = @QueueBinding(
value = @Queue(name = "dl.queue",durable = "true"),
exchange = @Exchange(name = "dl.direct"),
key = "dl"
))
public void listenDlQueue(String msg){
log.info("消费者接收到了 dl.queue的延迟消息");
}
再来一个新的配置类
package cn.itcast.mq.config;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* ClassName: TTLMessageConfig
* date: 2022/11/9 19:51
*
* @author DingJiaxiong
*/
@Configuration
public class TTLMessageConfig {
@Bean
public DirectExchange ttlDirectExchange() {
return new DirectExchange("ttl.direct");
}
@Bean
public Queue ttlQueue() {
return QueueBuilder
.durable("ttl.queue")
.ttl(10000)
.deadLetterExchange("dl.direct")
.deadLetterRoutingKey("dl")
.build();
}
@Bean
public Binding ttlBinding(){
return BindingBuilder.bind(ttlQueue()).to(ttlDirectExchange()).with("ttl");
}
}
OK, 启动消费者
OK,启动成功
测试,在生产者里面来一个测试方法
@Test
public void testTTLMessage() {
//1. 准备消息
Message message = MessageBuilder.withBody("Hello,ttl message".getBytes(StandardCharsets.UTF_8))
.setDeliveryMode(MessageDeliveryMode.PERSISTENT)
.build();
//2. 发送消息
rabbitTemplate.convertAndSend("ttl.direct","ttl",message);
//3. 记录日志,方便查看时间
log.info("消息已经成功发送了!");
}
直接运行测试
OK,注意这个时间
查看消费者的日志
几乎刚好10 s,牛逼!!!!!!!
这是基于队列,给队列设置的延迟时间 为 10s
再给消息设置一手
【发送消息时,给消息本身设置超时时间】
OK,再次运行测试
注意这个时间
OK,查看消费者日志
5s 没毛病,即队列和消息都设置了 超时时间时,以较短的为准
51.2.2 总结
消息超时的两种方式是?
- 给队列设置ttl属性,进入队列后超过ttl时间的消息变为死信
- 给消息设置ttl属性,队列接收到消息超过ttl时间后变为死信
- 两者共存时,以时间短的ttl为准
如何实现发送一个消息20秒后消费者才收到消息?
- 给消息的目标队列指定死信交换机
- 消费者监听与死信交换机绑定的队列
- 发送消息时给消息设置ttl为20秒
牛逼!!!!!!!