redis实现延迟消息队列 Spring boot
基于 spring boot 的重制版,对生产者、消费者进行了修改,实现定时的推送功能 base on delay-queue
1、分布式消费(未验证)
2、任务去重机制
3、多线程消费
4、相同时间点分组推送
5、修改线程为阻塞模式
6、消费推送异步
7、延时队列流程监控
最近在做一个排队取号的系统
类似的场景太多,最简单的解决办法就是定时任务去扫表。这样每个业务都要维护自己的扫表逻辑, 而且数据量越来越来越多的,有的数据可能会延迟比较大
经过一番搜索,网上说rabbitmq可以满足延迟执行需求,但是目前系统用了其他消息中间件,所以不打算用。
基于Redis实现的延迟消息队列java版:delay-queue
整个延迟队列由4个部分组成:
每个Job必须包含一下几个属性:
用户预约后,同时往JobPool里put一个job。job结构为:{‘topic':'book’, ‘id':'123456’, ‘delayTime’:1517069375398 ,’ttrTime':60 , ‘message':’XXXXXXX’} 同时以jobId作为value,delayTime作为score 存到bucket 中,用jodId取模,放到10个bucket中,以提高效率
timer每时每刻都在轮询各个bucket,按照score排序去最小的一个,当delayTime < 当前时间后,,取得job id从job pool中获取元信息。 如果这时该job处于deleted状态,则pass,继续做轮询;如果job处于非deleted状态,首先再次确认元信息中delay是否大于等于当前时间, 如果满足则根据topic将jobId放入对应的ready queue,然后从bucket中移除,并且;如果不满足则重新计算delay时间,再次放入bucket,并将之前的job id从bucket中移除。
消费端轮询对应的topic的ready queue,获取job后做自己的业务逻辑。与此同时,服务端将已经被消费端获取的job按照其设定的TTR,重新计算执行时间,并将其放入bucket。 消费端处理完业务后向服务端响应finish,服务端根据job id删除对应的元信息。如果消费端在ttr时间内没有响应,则ttr时间后会再收到该消息
实现思路 任务job内容包含Array{0,0,2m,10m,10m,1h,2h,6h,15h}和通知到第几次N(这里N=1, 即第1次). 消费者从队列中取出任务, 根据N取得对应的时间间隔为0, 立即发送通知.
第1次通知失败, N += 1 => 2 从Array中取得间隔时间为2m, 添加一个延迟时间为2m的任务到延迟队列, 任务内容仍包含Array和N
第2次通知失败, N += 1 => 3, 取出对应的间隔时间10m, 添加一个任务到延迟队列, 同上 ...... 第7次通知失败, N += 1 => 8, 取出对应的间隔时间15h, 添加一个任务到延迟队列, 同上 第8次通知失败, N += 1 => 9, 取不到间隔时间, 结束通知
参考有赞延迟队列思路设计实现
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。