可以使用Redis+Lua的方式来实现,大致的lua脚本代码如下:
- local key = "rate.limit:" .. KEYS[1] --限流KEY
- local limit = tonumber(ARGV[1]) --限流大小
- local current = tonumber(redis.call('get', key) or "0")
- if current + 1 > limit then --如果超出限流大小
- return 0
- else --请求数+1,并设置1秒过期
- redis.call("INCRBY", key,"1")
- redis.call("expire", key,"1")
- return current + 1
Java代码如下:
- public static boolean accquire() throws IOException, URISyntaxException {
- Jedis jedis = new Jedis("127.0.0.1");
- File luaFile = new File(RedisLimitRateWithLUA.class.getResource("/").toURI().getPath() + "limit.lua");
- String luaScript = FileUtils.readFileToString(luaFile);
- String key = "ip:" + System.currentTimeMillis()/1000; // 当前秒
- String limit = "5"; // 最大限制
- List<String> keys = new ArrayList<String>();
- keys.add(key);
- List<String> args = new ArrayList<String>();
- args.add(limit);
- Long result = (Long)(jedis.eval(luaScript, keys, args)); // 执行lua脚本,传入参数
- return result == 1;
- }
解释:
- Java代码传入key和最大的限制limit参数进lua脚本
- 执行lua脚本(lua脚本判断当前key是否超过了最大限制limit)
- 如果超过,则返回0(限流)
- 如果没超过,返回1(程序继续执行)
(编辑:晋中站长网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|