Toggle navigation
亻中 阝日
社区
VA伐木累
Proxy
JSON
BASE64
MyGit
登录
注册
×
登录
邮箱
密码
忘记密码?
NodeJS项目,使用Redis对用户访问量限流,Lua脚本
•发布于
•作者
liuzy
•671 次浏览
•最后一次编辑是
•来自
技术
- 第一版 ```lua --用户在M秒内请求超过N次,锁定M秒(在M秒后又可以访问N次) --await RD.eval(script, 1, 'uoffice:rate:zyliu', 10, 5); local K = KEYS[1] local M = tonumber(ARGV[1]) local N = tonumber(ARGV[2]) --次数自增 local times = redis.call('incr', K) --第一次 if times == 1 then redis.call('expire', K, M) return 0 end --次数大于N if times > N then return 1 end --次数小于N return 0 ``` - 第二版 ```lua --用户在M秒内请求超过N次,必须休息M秒才解锁 --await RD.eval(script, 1, 'uoffice:rate:zyliu', 10, 5); local K = KEYS[1] local M = tonumber(ARGV[1]) local N = tonumber(ARGV[2]) --次数自增 local times = redis.call('incr', K) redis.call('expire', K, M) --次数大于N if times > N then return 1 end --第一次或次数小于N return 0 ``` - 第三版 ```lua --准确获取用户在M秒内请求的次数 --await RD.eval(script, 1, 'uoffice:rate:zyliu', 10, Date.now()); local K = KEYS[1] local M = tonumber(ARGV[1]) --M秒内 local T = tonumber(ARGV[2]) --毫秒时间戳 --总条数 local len = redis.call('llen', K) --从未访问 if len == 0 then --插入本次到第0位 redis.call('lpush', K, T) redis.call('expire', K, M) return 0 end --从第0个开始遍历,数有多少个时间戳是M秒内的 local times = len for i = 0, len - 1 do local time = redis.call('lindex', K, i) if tonumber(time) + (M * 1000) < T then times = i break end end --仅保留M秒内数据 redis.call('ltrim', K, 0, times - 1) --插入本次到第0位 redis.call('lpush', K, T) redis.call('expire', K, M) --返回 return times ``` - 第四版 ```lua --保证用户在M秒内只能请求N次,超过返回操作过快 --await RD.eval(script, 1, 'uoffice:rate:zyliu', 10, 5, Date.now()); local K = KEYS[1] local M = tonumber(ARGV[1]) --M秒内 local N = tonumber(ARGV[2]) --N次 local T = tonumber(ARGV[3]) --毫秒时间戳 --当前次数 local len = redis.call('llen', K) --从未访问 if len == 0 then --插入本次到第0位 redis.call('lpush', K, T) redis.call('expire', K, M) return 0 end -- 从第0个开始遍历,数有多少个时间戳是M秒内的,最多数到N local times = len for i = 0, len - 1 do local time = redis.call('lindex', K, i) if tonumber(time) + (M * 1000) < T or i >= N then times = i break end end --仅保留M秒内最多N条数据 redis.call('ltrim', K, 0, times - 1) --插入本次到第0位 redis.call('lpush', K, T) redis.call('expire', K, M) --返回 if times >= N then return 1 else return 0 end ``` - 自动加载 ```js const fs = require('fs'); const path = require('path'); const lua = {}; const files = fs.readdirSync(__dirname); for (let i = 0; i < files.length; i++) { const file = path.join(__dirname, files[i]); if (path.extname(file) === '.lua') { const data = fs.readFileSync(file, 'utf-8'); lua[path.basename(file, '.lua')] = data.replace(/--[^\n].*[\n]+/gim, '\n').trim(); } } module.exports = lua; ```
NodeJS
Redis
Lua
0 回复
作者
liuzy
积分: 841
“ 黑眼圈圈男 ”
无人回复话题
SonarQube 9.4 + PostgreSQL
shell倒计时
日常网络巧技
使用ssh创建socks5代理服务
NodeJS集群demo
作者其他话题
SonarQube 9.4 + PostgreSQL
shell倒计时
日常网络巧技
使用ssh创建socks5代理服务
NodeJS集群demo
回到顶部
友情链接:
JFinal
©2015 Powered by
jfinalbbs
沪ICP备15012258号