延时队列的作用以及设计思路
延迟队列的应用
延迟队列在项目中应用有很多,尤其是像电商平台:
1、订单成功后,在三十分钟内没有支付,自动取消订单
2、外卖平台发送订餐通知,下单成功后60s给用户推送短信
3、如果订单一直处于某一个未完结状态时,及时处理关掉,并退还库存
4、淘宝新建商户一个月之内还没有上传商品信息,将冻结商铺等
。。。。
上面的情况都可以用到延时队列解决
如何构建延时队列
方案一:
底层用一个PriorityQueue优先队列(小顶堆)实现,将所有需要的的任务存在队列中,根据时间排序,延时时间短的先被消费者进行消费执行,while循环判断是否时间用完了,如果用完了就poll掉执行,然后继续轮询其他的任务
优点:使用成熟的数据结构,时间复杂度低,使用堆排序实现,稳定而且响应时间短
缺点;while循环在没有被执行的时候就会一直轮询,对cpu性能消耗较大
方案二:
通过date类来获取当前时间,截取小时和分钟判断是否相等于20:00 ,等于之后执行下单操作,加锁,防止多次执行,之后不让它结束,这个线程进入sleep状态,休眠1800s,支付操作完成后结束sleep状态,让线程结束,从队列当中取出这个值,未支付的haul睡醒之后也取出这个值
缺点:消耗cpu,任务多的话,系统崩溃
优点:设计简单,不用考虑时间问题
方案三:
以任务的过期时间为score,存入zset,设置定时任务的时间假如为1s,两种情况:
1:获取到的score
2:获取的score>当前时间,说明zset中该任务以及后面的所有任务都还没有到执行的时间,则休眠一秒后继续查询。
优点:zset也是成熟的结构,实现简单,redis中适量的加分布式锁之后,可以解决线程安全,基于内存,速度快。
缺点:还是需要去轮询任务,会造成不必要的cpu浪费