令牌桶允许短时突发流量,适合面向用户的开放 API;漏桶以恒定速率放行,适合保护脆弱的下游存储。网关层通常组合使用以实现分层防护。
![]()
一、Redis + Lua 实现原子令牌桶
lua
-- KEYS[1]=bucket key, ARGV[1]=rate, ARGV[2]=capacity, ARGV[3]=now
local rate = tonumber(ARGV[1])
local cap = tonumber(ARGV[2])
local now = tonumber(ARGV[3])
local data = redis.call("HMGET", KEYS[1], "tokens", "ts")
local tokens = tonumber(data[1]) or cap
local ts = tonumber(data[2]) or now
tokens = math.min(cap, tokens + (now - ts) * rate)
local allowed = 0
if tokens >= 1 then
tokens = tokens - 1
allowed = 1
end
redis.call("HMSET", KEYS[1], "tokens", tokens, "ts", now)
return allowed