本篇文章写 RabbitMQ
一个强大的功能 延迟队列。 在AMQP
协议中,或者 RabbitMQ
本身没有直接支持延迟队列的功能, 但是它可以通过过期时间(TTL)
和死信交换机(DLX)
模拟出延迟队列的功能。
[TOC]
延迟队列
延迟队列
存储的对象是对应的延迟消息。所谓“延迟消息”是指当消息被发送以后,并不想让消费者立刻拿到消息,而是在等待指定的时间后,消费者才能拿到这个消息进行消费。
延迟队列能做什么?
- 订单业务: 在电商/点餐中,都有下单后 30 分钟内没有付款,就自动取消订单。
- 短信通知: 下单成功后 60s 之后给用户发送短信通知。
- 失败重试: 业务操作失败后,间隔一定的时间进行失败重试。
这类业务的特点就是:非实时的,需要延迟处理,需要进行失败重试。一种比较笨的方式是采用定时任务,轮询数据库,方法简单好用,但性能底下,在高并发情况下容易弄死数据库,间隔时间不好设置,时间过大,影响精度,过小影响性能,而且做不到按超时的时间顺序处理。另一种就是用Java中的DelayQueue
位于java.util.concurrent
包下,本质是由PriorityQueue
和BlockingQueue
实现的阻塞优先级队列。这玩意最大的问题就是不支持分布式与持久化。
Time-To-Live Extensions
RabbitMQ支持为队列或者消息设置TTL(time to live 存活时间)。TTL表明了一条消息可在队列中存活的最大时间。当某条消息被设置了TTL或者当某条消息进入了设置了TTL的队列时,这条消息会在TTL时间后死亡成为Dead Letter。==如果既配置了消息的TTL,又配置了队列的TTL,那么较小的那个值会被取用==(一般情况下只需要设置其中一个就行了)。
Dead Letter Exchange
死信交换机,上文中提到设置了 TTL 的消息或队列最终会成为Dead Letter
。如果为队列设置了Dead Letter Exchange(DLX)
,那么这些Dead Letter
就会被重新发送到Dead Letter Exchange
中,然后通过Dead Letter Exchange
路由到其他队列,即可实现延迟队列的功能。
消息变成死信一般由一下三种情况:
- 消息被拒绝(
Basic.Reject
/Basic.Nack
),并设置requeue
参数为 false - 消息过期
- 队列达到最大长度
这篇笔记用的是消息过时,下一篇用的是消息过时 + 消息被拒绝。
环境/版本一览:
- 开发工具:Intellij IDEA 2018.2.2
- springboot: 2.0.6.RELEASE
- jdk:1.8.0_171
- maven:3.3.9
- spring-boot-starter-amqp: 2.0.6.RELEASE
1、pom.xml
1 | <dependencies> |
2、application.yml
1 | spring: |
3、config
1 | package com.fatal.config; |
4、entity
1 | package com.fatal.entity; |
5、consumer
1 | package com.fatal.consumer; |
6、controller
1 | package com.fatal.controller; |
7、显示
访问 http://localhost:8080/books
笔记
基础概念
Broker:简单来说就是消息队列服务器实体
Exchange:消息交换机,它指定消息按什么规则,路由到哪个队列
Queue:消息队列载体,每个消息都会被投入到一个或多个队列
Binding:绑定,它的作用就是把exchange
和queue
按照路由规则绑定起来,在绑定的时候一定会指定一个绑定键“Binding Key
”
Routing Key:路由关键字,exchange
根据这个关键字进行消息投递
vhost:虚拟主机,一个broker
里可以开设多个vhost
,用作不同用户的权限分离
producer:消息生产者,就是投递消息的程序
consumer:消息消费者,就是接受消息的程序
channel:消息通道,在客户端的每个连接里,可建立多个channel
,每个channel
代表一个会话任务
参考资料
一起来学SpringBoot | 第十三篇:RabbitMQ延迟队列
RabbitMQ 实战指南
总结
SpringBoot
的知识已经有前辈在我们之前探索了。比较喜欢的博主有:唐亚峰 | Battcn、方志朋的专栏、程序猿DD、纯洁的微笑。对这门技术感兴趣的可以去他们的博客逛逛。谢谢他们的分享~~
以上文章是我用来学习的Demo
,都是基于 SpringBoot2.x
版本。
源码地址: https://github.com/ynfatal/springboot2-learning/tree/master/chapter19_4