使用复述,怎么实现延迟队列

  介绍

本篇文章给大家分享的是有关使用复述,怎么实现延迟队列,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

方案一:

采用通过定时任务采用数据库/非关系型数据库轮询方案。

优点:

1。实现简单,对于项目前期这样是最容易的解决方案。

缺点:

1。数据库有效使用率低,需要将一部分的数据库的每秒分配给工作的无效轮询。

2。服务资源浪费,因为轮询需要对所有的数据做一次扫描扫描工作服务的资源开销很大。

方案二:

采用延迟队列:

优点:

1。服务的资源使用率较高,能够精确的实现超时任务的执行。

2。减少DB的查询次数,能够降低数据库的压力

缺点:

1。对于延迟队列来说本身设计比较复杂,目前没有通用的比较好过的方案。

基于复述的延迟队列实现

基于以上的分析,我决定通过复述来实现分布式队列。

设计思路:

使用复述,怎么实现延迟队列

1。第一步将需要发放的消息发送到延迟队列中。

2。延迟队列将数据存入复述的ZSet有序集合中得分为当前时间戳,成员存入需要发送的数据。

3。添加一个时间表来进行对复述有序队列的轮询。

4。如果到达达到消息的执行时间,那么就进行业务的执行。

5。如果没有达到消息的执行是将,那么消息等待下轮执行。

实现步骤:

由于本处篇幅有限,所以只列举部分代码,完整的代码可以在本文最后访问GitHub获取。由于本人阅历/水平有限,如有建议/或更正欢迎留言或提问。先在此谢谢大家驻足阅读吗?吗??。

需要注意的问题:

单个复述,命令的执行是原子性的,但复述,没有在事务上增加任何维持原子性的机制,所以复述,事务的执行并不是原子性的。

事务可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作,中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做。

我们可以通过复述的eval命令来执行lua脚本来保证原子性实现复述的事务。

实现步骤如下:

1。延迟队列接口

/* *   ,*延迟队列   ,*   ,* @author  zhengsh   ,* @date  2020-03-27   ,*/public  interface  RedisDelayQueue, {      ,,,String  META_TOPIC_WAIT =,“延迟:元:主题:wait";   ,,,String  META_TOPIC_ACTIVE =,“延迟:元:主题:active";   ,,,String  TOPIC_ACTIVE =,“延迟:活跃:9999“;;   ,,,/* *   ,,,,*,拉取消息   ,,,*/,,,void 调查();      ,,,/* *   ,,,,*,推送延迟消息   ,,,,   ,,,,*,@param  e   ,,,*/,,,void 推动(E  e);   }

2。延迟队列消息

/* *   ,*消息体   ,*   ,* @author  zhengsh   ,* @date  2020-03-27   ,*/@ setter   @ getter   public  class  DelayMessage  {   ,,,/* *   ,,,,*,消息唯一标识   ,,,*/,,,private  String  id;   ,,,/* *   ,,,,*,消息主题   ,,,*/,,,private  String  topic =,“default";   ,,,/* *   ,,,,*,具体消息,json   ,,,*/,,,private  String 身体;   ,,,/* *   ,,,,*,延时时间,,格式为时间戳:,当前时间戳,+,实际延迟毫秒数   ,,,*/,,,private  Long  delayTime =, System.currentTimeMillis (), +, 30000 l;   ,,,/* *   ,,,,*,消息发送时间   ,,,*/,,,private  LocalDateTime  createTime;   }

3。延迟队列实现

/* *   ,*延迟队列实现   ,*   ,* @author  zhengsh   ,* @date  2020-03-27   ,*/@ component   public  class  RedisDelayQueueImpl, implements  RedisDelayQueue, {   ,,,private  Logger  Logger =, LoggerFactory.getLogger (getClass ());      ,,@ autowired   ,,,private  StringRedisTemplate  redisTemplate;      ,,@Override   ,,,public  void 调查(),{   ,,,,,,,//todo   ,,,}      ,,,/* *   ,,,,*,发送消息   ,,,,   ,,,,*,@param  e   ,,,*/,,@SneakyThrows   ,,@Override   ,,,public  void 推动(E  e), {   ,,,,,,,try  {   ,,,,,,,,,,,String  jsonStr =, JSON.toJSONString (e);   ,,,,,,,,,,,String  topic =, e.getTopic ();   ,,,,,,,,,,,String  zkey =, String.format(“延迟:等:% s",,主题);   ,,,,,,,,,,String  u =,,,,,,,,,,,,,,,,,,,“redis.call(& # 39;大块漂浮植物# 39;,,键[1],ARGV [1]) \ n" +   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null

使用复述,怎么实现延迟队列