3.1 什么是延迟队列
延迟队列顾名思义队列里面存放的都是延迟消息;“延迟消息”是值消费者发送消息后,不想让消费者立刻获取到消息,需要等待一定时间后才能被消费掉(和定时任务概念一样)。
使用场景:
在x宝下单后30分钟内没有完成支付,就需要针对当前订单进行一场处理(回滚库存)
预约课程后,需要提前1小时提醒用户参加课程
3.2 如何使用延迟队列?
RabbitMQ中的延迟队列是利用 过期时间+死信队列 两个特性来实现,实现思路如下:
如上图所示:分别创建5s、10s的过期队列,等到超时后MQ会自动将这些消息投递到设置的死信队列中,然后消费者就可以从死信队列中接收消息来实现延迟接收消息效果。
3.3 定义延迟队列
3.3.1 创建延迟队列
在spring/spring-rabbitmq.xml文件,添加如下内容:
3.3.2 创建死信交换机/队列
在spring/spring-rabbitmq.xml文件,添加如下内容:
3.4 延迟队列测试
3.4.1 编写发送消息代码
在ProducerTest.java类增加如下方法:
/** * * 功能描述: 过期后的消息投递到死信队列 * 消息将会被投递到正常的队列,队列有分别设置5s、10s有效时间,超过时间后消息被投递到死信交换机(队列) */@Testpublic void messageDelayQueueTest(){ rabbitTemplate.convertAndSend("wx_delay_exchange", "wx_5s_delay", "消息1:测试过期后的消息投递到死信交换机,有效时间5s"); rabbitTemplate.convertAndSend("wx_delay_exchange", "wx_10s_delay", "消息2:测试过期后的消息投递到死信交换机,有效时间10s");}
3.4.2 投递过程说明
第一步:生产者将“消息1:测试过期后的消息投递到死信交换机,有效时间5s”和“消息2:测试过期后的消息投递到死信交换机,有效时间10s”消息分别投递到名称为wx_delay_exchange的交换机,路由key分别为wx_5s_delay和wx_10s_delay。
第二步:wx_5s_delay路由key绑定到5s_delay_dlx_queue队列中,wx_10s_delay路由key绑定到10s_delay_dlx_queue队列中。
第三步:设置5s_delay_dlx_queue的超时时间为5s,设置10s_delay_dlx_queue的超时时间为10s,超时后消息将被投递到wx_delay_dlx_exchange死信交换机中。
第四步:设置wx_delay_dlx_exchange死信交换机的路由key为wx_5s_delay和wx_10s_delay(和生产者投递消息的路由key保持一致)
第五步:将wx_delay_dlx_exchange死信队列设置的wx_5s_delay和wx_10s_delay路由key绑定到wx_delay_dlx_queue死信队列中。
3.4.3 测试验证
运行代码,登录RabbitMQ管理端,未过期消息如下所示:
和预期一样创建了3个队列,5s_delay_dlx_queue和10s_delay_dlx_queue可以看做为临时队列用于存放有效期内的消息,当消息过期后会自动投递到wx_delay_dlx_queue死信队列中。