延时任务队列

单机支持每秒10万延时消息高效触发(可部署多台提供更高并发) 环境:JDK7以上。

源码根目录有ppt文档。

本文方案是看了58的一位架构师的分享,但并没有实现细节。本文是对方案的深入研究及代码实现

延时任务队列 业务场景

1.下单之后如果三十分钟之内或12小时没有付款就自动取消订单

2.下单成功后60s之后给用户发送短信通知

3.用户希望通过手机远程遥控家里的智能设备在指定的时间进行工作。这时候就可以将用户指令发送到延时队列,当指令设定的时间到了再将指令推送到只能设备。

  1. 七天自动收货

5.一定时间后自动评价

6.业务执行失败之后隔10分钟重试一次

…….

本质都是过一段时间后才执行任务

下单成功后60s之后给用户发送短信通知为例。

延时任务队列 方案一: 定时扫描表

实现:启动一个定时任务,每分钟查一次数据库表,把下单成功超过60秒并且没有发过短信通知的的取出来,然后去处理。

缺点: 1.如果数据量很大,查表轮询效率就低。 2.每分钟轮询一次增加了数据库压力。 3.如果是增大轮询时间间隔,那么时效性(准确性)又降低了

延时任务队列 方案二: redis

实现:通过zset机构模拟,定时器去读zset数据去处理。

不足:

1.数据量大,一zset性能有问题。 当然可以多定义几个zset,再数据量大的时候分散到不同zset里面,但存和定时器去读的复杂性增加了。 2.消息处理失败是不能被恢复。也有考虑过将分为TODO和Doing两条队列。但是由于Redis的事务特性,并不能做到完全可靠;并且检查Doing超时的逻辑也略复杂 并不是成熟方案,需要自己去实现。

延时任务队列 方案三: JAVA DelayQueue

实现:DelayQueue本身就是延迟队列

不足:

1.通过先将消息排序再定时触发的方式来实现延迟消息。所以大量消息时,性能不能保证 2.想提供一定可靠性(如数据持久性),扩展性不方便 3.分布式需要额外实现

延时任务队列 方案四: MQ

实现:老版本的MQ大多没有延时队列的实现。 不过现在新版本慢慢有了延时投递的功能。 如:ActiveMQ 可以延时投递,但有人测试在往队列中投递大量(10w+)定时消息之后,ActiveMQ的性能将会变得接近不可用,大量的消息挤压得不到投递,可多机。 RocketMQ 支持定时消息,但是不支持任意时间精度,支持特定的level,例如定时5s,10s,1m等。 RabbitMQ 通过他的一些特性也可以模拟出延迟队列的功能,或者有一些第三方插件

完善的MQ系统可实现一个高可靠的分布式延迟消息队列。仍在发展中,但还没有完全比较专用的延迟消息功能

延时任务队列 方案五: 自己实现延时MQ 有能力可以做,mq实现起来还是耗费资源的

延时任务队列 方案六: 自己实现延时队列

我们自己实现轻量级的延时队列。

初级版本目标: 网络或down机允许消息丢失。即业务完整性不保证 支持高并发 不提供客户端 只做一个内嵌的jar,不单独做一个成品应用服务

延时任务队列

延时任务队列

延时任务队列

延时任务队列