基于Redis+Lua的分布式限流
local redis = require 'resty.redis'
local red = redis:new()
-- 设置超时时间
red:set_timeout(1000)
-- 连接Redis
local ok, err = red:connect(os.getenv('REDIS_HOST'), os.getenv('REDIS_PORT'))
if not ok then
ngx.log(ngx.ERR, "连接Redis失败: ", err)
return ngx.exit(500)
end
-- 用Lua脚本实现限流
local limit_key = ngx.var.binary_remote_addr .. ":" .. ngx.var.uri
local num = tonumber(ngx.var.arg_num) or 1
local rate = tonumber(ngx.var.arg_rate) or 10
local burst = tonumber(ngx.var.arg_burst) or 100
local script = [[
local key = KEYS[1]
local rate = tonumber(ARGV[1])
local burst = tonumber(ARGV[2])
local requested = tonumber(ARGV[3])
local allowed = burst
local current = redis.call('get', key)
if current then
current = tonumber(current)
if current + requested > allowed then
return current
else
redis.call('incrby', key, requested)
end
else
redis.call('set', key, 0)
redis.call('pexpire', key, 1000)
end
return requested
]]
local res, err = red:eval(script, 1, limit_key, rate, burst, num)
if not res then
ngx.log(ngx.ERR, "Lua脚本执行失败: ", err)
return ngx.exit(500)
end
if res > burst then
ngx.say("超出限制")
ngx.exit(403)
else
ngx.say("通过限流")
end
这段代码使用了Lua脚本在Redis中实现了一个简单的限流机制。它首先连接到Redis,然后使用Lua脚本来控制访问频率。脚本会检查当前的请求数是否超过设定的限制,并相应地处理请求。这个例子展示了如何结合Redis和Lua脚本来实现分布式限流。
评论已关闭