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有专业的延迟队列
-
本文来自博客园,作者:SArtOnline,转载请注明原文链接:https://www.cnblogs.com/sartonline/p/16134016.html