Redis + Lua 实现分布式限流器
-- 引入Redis和Redis连接池模块
local redis = require 'resty.redis'
local red = redis:new()
-- 连接Redis
red:set_timeout(1000) -- 设置超时时间
local ok, err = red:connect('127.0.0.1', 6379)
if not ok then
ngx.say("连接Redis失败: ", err)
return
end
-- 为了简化,这里不使用密码进行连接
-- 初始化限流器参数
local limit = 100 -- 每秒允许的最大请求数
local window = 1 -- 时间窗口,这里为1秒
local counter_key = "rate_limit_counter" -- Redis中计数器的键
local lock_key = "rate_limit_lock" -- 用于分布式锁的键
-- 获取分布式锁,避免并发更新计数器时的数据竞争
local ok, err = red:setnx(lock_key, true)
if not ok then
ngx.say("获取分布式锁失败: ", err)
return
end
-- 检查是否已经有其他请求获得了分布式锁,如果是,则等待下一次尝试
if err == 0 then
ngx.say("已达到限流限制")
return
end
-- 计数器存在,获取当前计数
local current_count = tonumber(red:get(counter_key) or 0)
-- 如果计数器超过限制,则等待下一个时间窗口
if current_count >= limit then
ngx.say("已达到限流限制")
return
end
-- 计数器未超过限制,增加计数
current_count = current_count + 1
red:set(counter_key, current_count)
-- 解锁
red:del(lock_key)
-- 业务逻辑继续执行...
ngx.say("请求通过限流器")
这段代码示例展示了如何使用Redis和Lua脚本在Nginx环境中实现一个简单的分布式限流器。它使用Redis的计数器和分布式锁来控制请求的频率。在实际应用中,你可能需要根据具体需求调整限流器的参数和逻辑。
评论已关闭