Redis + luaはスライディングウィンドウの電流制限を実装します

序文

スライディングタイムウィンドウアルゴリズムとより多くの電流制限の実践については、以下をご覧ください:インターフェース電流制限の実践

脚本

これは主に、順序付けられたredisのセット(zset)を使用して実現されます。前の秒の訪問数を計算するには、zcountコマンドを主に使用して、現在のセットの指定された間隔スコアのメンバー数を計算します。 luaスクリプトは使用されず、各コマンドが呼び出されます同時実行の隠れた危険性があり、redisはluaスクリプト全体をコマンドとして実行して、アトミック操作を保証し、同時実行を心配する必要がありません。すべての計算ロジックをスクリプト。スクリプトは次のとおりです。

local key = KEYS[1]
-- 一个时间窗口限制数量
local limitCount = tonumber(ARGV[1])
-- 获取当前时间,单位毫秒
local currentTime = tonumber(ARGV[2])
-- 当前时间戳的key值,唯一
local timeKey = ARGV[3]
-- 获取时间窗口范围,传参单位秒,默认窗口一秒
local timeRange
if ARGV[4] == nil then
	timeRange = 1000
else
	timeRange = tonumber(ARGV[4]) * 1000
end
-- 获取集合key过期时间,当key过期时会存在瞬时并发的情况,因此过期时间不能太短或者改用定时清除,传参单位秒,默认一小时
local expiration
if ARGV[5] == nil then
	expiration = 3600
else
	timeRange = tonumber(ARGV[5])
end
-- 前一秒内已访问的次数
local beforeCount = 0
local existKey = redis.call('exists', key)
if (existKey == 1) then
	-- 计算前一秒访问次数
	beforeCount = redis.call('zcount', key, currentTime - timeRange, currentTime)
end
-- 记录当前访问时间
redis.call('zadd', key, currentTime, timeKey)
local result = 0
if (limitCount > beforeCount) then
	result = 1
end
-- 设置过期时间
redis.call('expire', key, expiration)
return result

順序セット内のキーは一意である必要があり、タイムスタンプは使用できないことに注意してください。

おすすめ

転載: blog.csdn.net/m0_38001814/article/details/113643374