Redis延迟队列

 

一、应用场景

  • 提交订单30分钟未支付,自动取消订单

  • 流程挂起2小时后,自动恢复流程

二、工作原理

Redis高性能 + 定时任务 + zset

zset:设置时间戳作为score,每次取即将过期任务执行

定时任务:轮询zset,取出到期任务执行

三、用例

  • 提交延迟任务

jedis.zadd(queueKey, System.currentTimeMillis() + 5000, orderId2);

  • 消费延迟任务

Set<String> resultList = jedis.zrangebyscore(key, System.currentTimeMillis(), 0, 1);
if(resultList.size() > 0) {
   if(jedis.zrem(key, resultList.get(0)) > 0) {
       handleMsg(resultList.get(0));
  }
}
  • 消费延迟任务(lua脚本优化:合并获取和删除操作)

String luaScript = "local resultArray = redis.call('zrangebyscore', KEYS[1], 0, ARGV[1], 'limit' , 0, 1)\n" +
       "if #resultArray > 0 then\n" +
       "   if redis.call('zrem', KEYS[1], resultArray[1]) > 0 then\n" +
       "       return resultArray[1]\n" +
       "   else\n" +
       "       return ''\n" +
       "   end\n" +
       "else\n" +
       "   return ''\n" +
       "end";
jedis.eval(luaScript, ScriptOutputType.VALUE, new String[]{key}, String.valueOf(System.currentTimeMillis()));

四、SWOT分析

  • S:内存读写快,可持久化

  • W:没有ACK和重试机制

  • O:专业版MQ没Redis快

  • T:RabbitMQ有专业的延迟队列

  •  

posted @ 2022-04-12 10:39  SArtOnline  阅读(212)  评论(0编辑  收藏  举报