环境:JDK7以上。git
源码根目录有ppt文档。redis
本文方案是看了58的一位架构师的分享,但并无实现细节。本文是对方案的深刻研究及代码实现数据库
:exclamation: 业务场景网络
1.下单以后若是三十分钟以内或12小时没有付款就自动取消订单架构
2.下单成功后60s以后给用户发送短信通知并发
3.用户但愿经过手机远程遥控家里的智能设备在指定的时间进行工做。这时候就能够将用户指令发送到延时队列,当指令设定的时间到了再将指令推送到只能设备。 4.七天自动收货分布式
5.必定时间后自动评价高并发
6.业务执行失败以后隔10分钟重试一次性能
…….测试
本质都是过一段时间后才执行任务
下单成功后60s以后给用户发送短信通知为例。
:exclamation: 方案一: 定时扫描表
实现:启动一个定时任务,每分钟查一次数据库表,把下单成功超过60秒而且没有发太短信通知的的取出来,而后去处理。
缺点: 1.若是数据量很大,查表轮询效率就低。 2.每分钟轮询一次增长了数据库压力。 3.若是是增大轮询时间间隔,那么时效性(准确性)又下降了
:exclamation: 方案二: redis
实现:经过zset机构模拟,定时器去读zset数据去处理。
不足:
1.数据量大,一zset性能有问题。 固然能够多定义几个zset,再数据量大的时候分散到不一样zset里面,但存和定时器去读的复杂性增长了。 2.消息处理失败是不能被恢复。也有考虑过将分为TODO和Doing两条队列。可是因为Redis的事务特性,并不能作到彻底可靠;而且检查Doing超时的逻辑也略复杂 并非成熟方案,须要本身去实现。
:exclamation: 方案三: JAVA DelayQueue
实现:DelayQueue自己就是延迟队列
不足:
1.经过先将消息排序再定时触发的方式来实现延迟消息。因此大量消息时,性能不能保证 2.想提供必定可靠性(如数据持久性),扩展性不方便 3.分布式须要额外实现
:exclamation: 方案四: MQ
实现:老版本的MQ大多没有延时队列的实现。 不过如今新版本慢慢有了延时投递的功能。 如:ActiveMQ 能够延时投递,但有人测试在往队列中投递大量(10w+)定时消息以后,ActiveMQ的性能将会变得接近不可用,大量的消息挤压得不到投递,可多机。 RocketMQ 支持定时消息,可是不支持任意时间精度,支持特定的level,例如定时5s,10s,1m等。 RabbitMQ 经过他的一些特性也能够模拟出延迟队列的功能,或者有一些第三方插件
完善的MQ系统可实现一个高可靠的分布式延迟消息队列。仍在发展中,但尚未彻底比较专用的延迟消息功能
:exclamation: 方案五: 本身实现延时MQ 有能力能够作,mq实现起来仍是耗费资源的
:+1: 方案六: 本身实现延时队列
咱们本身实现轻量级的延时队列。
初级版本目标: 网络或down机容许消息丢失。即业务完整性不保证 支持高并发 不提供客户端 只作一个内嵌的jar,不单独作一个成品应用服务
具体见: https://gitee.com/itman666/wheel-timer-queue/wikis/Home