基于Springbootredis实现延时队列
什么是延迟队列?
首先,队列这种数据结构相信大家都不陌生,它是一种先进先出的数据结构。普通队列中的元素是有序的,先进入队列中的元素会被优先取出进行消费;
延时队列相比于普通队列最大的区别就体现在其延时的属性上,普通队列的元素是先进先出,按入队顺序进行处理,而延时队列中的元素在入队时会指定一个延迟时间,表示其希望能够在经过该指定时间后处理。从某种意义上来讲,延迟队列的结构并不像一个队列,而更像是一种以时间为权重的有序堆结构。应用场景下单成功后,X分钟内没有支付,自动取消订单外卖场景,快要超时时给外卖小哥发送提醒通知预定的会议开始前X分钟提醒等等方案JDK中DelayQueue相关APIQuartzRedisZset(本文)MQ等等实现
本文使用RedisZset来实现延迟队列。
zset是Redis提供的最具特色的数据类型之一,首先它是一个set,这保证了内部value值的唯一性,其次它给每个value添加了一个score(分值)属性,通过对分值的排序实现了有序化。比如用zset结构来存储学生的成绩,value值代表学生的ID,score则是的考试成绩。我们可以对成绩按分数进行排序从而得到学生的的名次。
1、pom。xmldependencygroupIdorg。springframework。bootgroupIdspringbootstarterdataredisartifactIddependency
application。ymlspring:redis:host:localhostport:6379password:xxxdatabase:1
2、延迟任务对象定义publicinterfaceRedisDelayTask{任务IDreturnStringgetId();队列中的值returnStringgetValue();延迟时间(单位:s)returnlonggetDelayTime();任务执行voidexecute();}抽象任务publicabstractclassAbstractRedisDelayTaskimplementsRedisDelayTask{protectedStringid;protectedStringvalue;privatelongdelayTime;publicAbstractRedisDelayTask(Stringid,Stringvalue,longdelayTime){this。idid;this。valuevalue;this。delayTimedelayTime;}OverridepublicStringgetId(){returnid;}publicvoidsetId(Stringid){this。idid;}OverridepublicStringgetValue(){returnvalue;}publicvoidsetValue(Stringvalue){this。valuevalue;}OverridepubliclonggetDelayTime(){returndelayTime;}publicvoidsetDelayTime(longdelayTime){this。delayTimedelayTime;}OverridepublicStringtoString(){returnRedisDelayTask{idid,valuevalue,delayTimedelayTime};}}
3、通知类任务定义publicclassNoticeTaskextendsAbstractRedisDelayTask{privatefinalstaticLoggerLOGGERLoggerFactory。getLogger(NoticeTask。class);publicNoticeTask(Stringid,Stringvalue,longdelayTime){super(id,value,delayTime);}Overridepublicvoidexecute(){LOGGER。info(taskexecute,{},this);}}
4、任务管理ComponentpublicclassRedisDelayQueueManagerimplementsInitializingBean{AutowiredprivateStringRedisTemplateredisTemplate;任务列表privateMapString,RedisDelayTasktasksnewConcurrentHashMap();添加延迟任务到队列paramtaskpublicvoidaddTask(RedisDelayTasktask){longdelayedTimeSystem。currentTimeMillis()TimeUnit。MILLISECONDS。convert(task。getDelayTime(),TimeUnit。SECONDS);booleanrredisTemplate。opsForZSet()。add(task。getId(),task。getValue(),delayedTime);if(r){tasks。put(task。getId(),task);}}检查并执行任务privatevoidcheckAndExecuteTask(){while(true){SetStringtaskIdstasks。keySet();for(StringtaskId:taskIds){score就是任务要执行的时间点,如果当前时间,说明任务该执行了SetZSetOperations。TypedTupleStringtuplesredisTemplate。opsForZSet()。rangeByScoreWithScores(taskId,0,System。currentTimeMillis());if(!CollectionUtils。isEmpty(tuples)){for(ZSetOperations。TypedTupleStringtuple:tuples){移除并执行任务RedisDelayTasktasktasks。remove(taskId);if(task!null){task。execute();从队列中删除redisTemplate。opsForZSet()。remove(taskId,tuple。getValue());}}}}}}OverridepublicvoidafterPropertiesSet()throwsException{新起一个线程执行任务newThread((){checkAndExecuteTask();},redisdelaytask)。start();}}
5、测试RunWith(SpringRunner。class)SpringBootTest(classesRedisApplication。class)publicclassRedisDelayTaskTest{AutowiredprivateRedisDelayQueueManagerredisDelayQueueManager;TestpublicvoidaddTask()throwsIOException{NoticeTasktasknewNoticeTask(noticetask,noticetaskvalue,5);redisDelayQueueManager。addTask(task);NoticeTasktask2newNoticeTask(noticetask2,noticetaskvalue2,10);redisDelayQueueManager。addTask(task2);System。in。read();}}
执行结果如下:2022012217:27:53。428INFO86506〔main〕io。lettuce。core。KqueueProvider:Startingwithoutoptionalkqueuelibrary
2022012217:27:58。140INFO86506〔edisdelaytask〕c。springboot。demo。redis。task。NoticeTask:taskexecute,RedisDelayTask{idnoticetask,valuenoticetaskvalue,delayTime5}
2022012217:28:03。925INFO86506〔edisdelaytask〕c。springboot。demo。redis。task。NoticeTask:taskexecute,RedisDelayTask{idnoticetask2,valuenoticetaskvalue2,delayTime10}
a16z为美国政府提议去中心化友好的监督制度链得得(微信号:ChainDD)10月06日讯,据CoinDesk报道,风险投资公司AndreessenHorowitz(a16z)提出了美国政府可以管理加密货币和区块链技术的……
人类大脑是一条机器狗很想要分享最近在看的一篇文章,来自丹麦奥胡斯大学认知科学的MikkelWallentin写的,人类大脑是一条狗,也许是条机器狗。这篇文章主要讲的呢是人类的大脑和意识。随着……
华为HarmonyOS2系统发布!网友牛逼LOGO大师整理编辑(ID:logods)图片来源:HarmonyOS官微、华为官微部分资料参考:华为官方还记得在2019年美国宣布禁止华为使用安卓系统……
被网友锤爆?opporeno6拿什么反击近日,oppo发布了新机,OPPOreno6系列手机。对此很多网友都说OPPOreno6系列手机,看了价格后,很多网友都说不香了。那么事实是怎么样的呢。就拿oppo……
苹果13和苹果12性能对比到底谁更香?苹果发布会后,很多人直夸苹果业界良心,13增量又降价,13真的香!可13真的香么?我给准备购买iphone13的用户带来灵魂三问,看完你再问问自己13到底香不香。1……
新能源,我们要细化行业知识颗粒度新能源在汽车市场可以说是非常或火爆,引起很多消费者的关注,近期,孟浩身为鹏华基金的工作人士,对新能源知识给了一些分享,看看他是如何寻找当时最具活力的资产的。新能源投资需要……
又一国产5G巨头杀出?入局德国5G市场,雷军这次究竟在下什么这也叫5g巨头?大家都知道,经过了将近10年的努力,小米公司再一次超越苹果,成为了全球第三大智能手机品牌,目前我国的华为和小米直接是占据了全球前三的两个位置,但是目前华为……
天融信一季报营收增长逾四成技术创新聚焦新场景4月29日晚,天融信(002212)发布2022年一季报,报告期内,公司实现营业收入3。78亿元,同比增长42。80;毛利率为67。64,同比上升7。69个百分点。期间费用总计……
标题党真恶心,应该严惩随着互联网产业的迅速发展,现在的社交平台是越来越多。而进入社交平台的门槛儿也越来越低。因为注册一个社交平台账号很容易,它不需要任何工作经验,不需要任何学历,更不需要任何资金。大……
时隔1269天,魅蓝回归,魅族再一次推翻了自己魅族正在不断推翻自己。今年3月,魅族18系列发布会上,魅族官方高调宣布:从18系列开始,魅族将放弃新产品的互联网广告营收,为消费者提供真正的纯净硬件、纯净系统,打造……
怎么看待现在的今日头条?没有头条的时候,下着无聊看看百度,不管查什么都是百度,自打有了头条,就感觉头条新闻,生活、娱乐什么都有而且都是新鲜出炉,他有文章、微头条,视频、小视频,问答,形式多样化,想查什……
华为P50上市被迫继续延期特斯拉法务部私信警告自媒体热点聚焦1。【华为发布P50系列手机,暂未公布具体上市日期】华为正式发布HarmonyOS2及多款搭载HarmonyOS2的新产品。华为手机、平板等百款设备将陆续启动升级……