使用一个延时队列,利用redis的zset(sort set,有序不重复集合,关联分数score进行排序),将提醒时间作为分数,提取符合条件的score对应的集合发起提醒(本文所述也是围绕这个方案) 二、延时队列的基本操作流程 基本流程图 代码实现 生产者,只关心数据进队列 publicclassMessageProvider{// 延时队列的服务 通过这个bean来统一...
生产者将需要延迟发送的数据放入redis zset中 # key为队列的名称,score为当前的时间戳+延迟时间,member为消息体 zadd key score member 1. 2. 2.消费者一直循环从redis的zset队列获取数据 # key为队列的名称,min为0,max为当前的时间戳,limit为单次个数 zrangebyscore key min max limit 1. 2. 然后将该消息...
1. 将延迟任务加入Zset 首先,我们需要将待执行的任务添加到Zset中,并设置任务的执行时间。使用Redis的ZADD命令可以实现这一步骤。 ZADD queue:<queue_name><task_id> 1. <queue_name>:队列名称,可以根据业务需要自定义,例如queue:delay。 :任务执行的时间戳,可以使用当前时间加上延迟时间来设置,例如time.time()...
延迟队列可以通过 zset 来实现,因为 zset 中有一个 score,我们可以把时间作为 score,将 value 存到 redis 中,然后通过轮询的方式,去不断的读取消息出来 整体思路 1.消息体设置有效期,设置好score,然后放入zset中 2.通过排名拉取消息 3.有效期到了,就把当前消息从zset中移除 我们来看看,zset有哪些命令: 可以...
使用redis的有序集合zset实现延迟队列,核心就在score分值上,通过当前时间加上延迟时间作为score,使用zremrangebyscore 命令取出0到当前时间(long型)的元素,能够取出来的就是过期的元素。当然,这个算法也存在不足之处,在取值的时候,采用了轮询,会白白地浪费一部分性能。当然我们主要是了解这个算法是怎么实现的。
总结一下php使用redis的有序集合zset实现延迟队列 将消息数据序列化,作为zset发基本元素,把 消息生产时间戳+消息处理延迟时间戳 作为score,每次通过 zRangeByScore获取一条消息进行处理,后通过zRem删除集合元素,相当于移除需要消费的Job,浅谈一下优点: 实现简单,适合做中小型对延迟时间要求不高的业务场景 ...
基于zset实现的延迟队列,可以封装成两种方式供业务调用。 本地化starter调用:将于redis的zset交互过程抽象成starter,然后业务服务依赖封装好的starter,实现本地化延迟队列调用,也就是说交互过程被封装,实际上与redis交互以及延迟事件上报、事件消费和回调都在业务服务进行。
{this.zset=zset;this.uid=uid;}@Overridepublicvoidrun(){// TODO 执行具体的业务逻辑Longnow=System.currentTimeMillis();log.info("计划执行时间:{}, 实际执行时间:{},set={}",format.format(zset.score("AA",uid).longValue()),format.format(now),uid);// 从redis缓存中移除zset.remove("AA",...
延迟队列可以通过 zset 来实现,因为 zset 中有一个 score,我们可以把时间作为 score,将 value 存到 redis 中,然后通过轮询的方式,去不断的读取消息出来。 首先,如果消息是一个字符串,直接发送即可,如果是一个对象,则需要对对象进行序列化,这里我们使用JSON来实现序列化和反序列化。