延迟队列&死信队列
一、延迟队列&死信队列基本介绍
-
延迟队列——消息进入到队列之后,延迟指定的时间才能被消费者消费(设置了消息过期时间的队列称之为延迟队列)
-
AMQP协议和RabbitMQ队列本身是不支持延迟队列功能的,但是可以通过TTL(Time To Live)特性模拟延迟队列的功能
-
TTL就是消息的存活时间。RabbitMQ可以分别对队列和消息设置存活时间
-
在创建队列的时候可以设置队列的存活时间,当消息进入到队列并且在存活时间内没有消费者消费,则此消息就会从当前队列被移除;
-
创建消息队列没有设置TTL,但是消息设置了TTL,那么当消息的存活时间结束,也会被移除;
消息过期,消息就成了死信
- 当TTL结束之后,我们可以指定将当前队列的消息转存到其他指定的队列(接收死信消息的队列就是死信队列)
二、demo实战
场景介绍:用户购物场景,在用户下完单后,30s内未完成支付,则自动取消订单。本章通过RabbitMQ的方式实现,将通过延迟队列和死信队列实现。
主要工作流程如图:
先创建数据表结构:
CREATE TABLE `orders` (
`id` varchar(255) COLLATE utf8_bin NOT NULL,
`name` varchar(255) COLLATE utf8_bin DEFAULT NULL,
`type` int DEFAULT NULL COMMENT '0:未支付,1:已支付,2:已取消,默认0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
common模块常量新增如下常量:
父工程添加依赖:
新增延时队列、死信队列以及交换机的配置类TopicDelayConfig
@Configuration
public class TopicDelayConfig {
// 路由交换机
@Bean
public DirectExchange directExchange() {
return new DirectExchange(RabbitMQConstant.DELAY_DEAD_EXCHANGE, true, false);
}
// 延迟队列 延迟30s
// 30s后,将死信消息发送给交换机
@Bean
public Queue delayQueue() {
HashMap<String, Object> map = new HashMap<>();
// x-dead-letter-exchange 当消息过期变成死信后重新发送到交换机
map.put("x-dead-letter-exchange", RabbitMQConstant.DELAY_DEAD_EXCHANGE);
// x-dead-letter-routing-key 当死信到达交换机,根据路由值发送到指定的死信队列
map.put("x-dead-letter-routing-key", RabbitMQConstant.ROUTER_KEY_DEAD);
// x-message-ttl 队列中消息过期时间 30s
map.put("x-message-ttl", 30000);
return new Queue(RabbitMQConstant.DELAY_QUEUE, true, false, false, map);
}
// 死信队列
@Bean
public Queue deadQueue() {
return new Queue(RabbitMQConstant.DEAD_QUEUE, true);
}
// 队列交换机绑定关系
@Bean
public Binding binding1() {
return BindingBuilder.bind(delayQueue()).to(directExchange()).with(RabbitMQConstant.ROUTER_KEY_DELAY);
}
@Bean
public Binding binding2() {
return BindingBuilder.bind(deadQueue()).to(directExchange()).with(RabbitMQConstant.ROUTER_KEY_DEAD);
}
}
简要说明:这里的配置交换机为路由交换机,会根据路由值精准匹配消息队列
- 主要配置一个延迟死信交换机
- 配置延迟队列,配置消息有效时间(30s),30s后,死信达到配置交换机且路由值为死信队列路由值
- 配置死信队列,接收死信消息
- 配置延迟队列、死信队列与延迟死信交换机的绑定关系
新增订单实体类:
provider模块配置文件新增数据库配置:(数据库操作都写在provider模块,图方便~)
创建订单接口:
新增死信队列监听器:
postman测试:
订单创建成功
30s后,订单取消成功