Jim*_*Jim 2 rate-limiting redis
我已阅读此处的INCR 文档,但我无法理解为什么速率限制器 2 有竞争条件。
另外,the key will be leaked until we'll see the same IP address again文档中的意思是什么?
谁能帮忙解释一下吗?非常感谢!
您正在谈论以下代码,它在多线程环境中存在两个问题。
1. FUNCTION LIMIT_API_CALL(ip):
2. current = GET(ip)
3. IF current != NULL AND current > 10 THEN
4. ERROR "too many requests per second"
5. ELSE
6. value = INCR(ip)
7. IF value == 1 THEN
8. EXPIRE(ip,1)
9. END
10. PERFORM_API_CALL()
11.END
Run Code Online (Sandbox Code Playgroud)
密钥将会被泄露,直到我们再次看到相同的 IP 地址
如果客户端在执行之前死亡,例如客户端被杀死或机器停机LINE 8。那么密钥ip就不会被设置过期。如果我们再也不会看到这个ip,这个密钥将永远保留在 Redis 数据库中,并且会被泄露。
速率限制器 2 有竞争条件
假设ip数据库中不存在该键。如果有多个10客户端(例如客户端),请同时20执行。LINE 2他们所有人都会得到一个NULL current,并且他们都会进入该ELSE条款。最后所有这些客户端都会执行LINE 10,并且API将被调用多次10。
LINE 2该解决方案失败了,因为这是和之间的时间窗口LINE 3。
正确的解决方案
value = INCR(ip)
IF value == 1 THEN
EXPIRE(ip, 1)
END
IF value <= 10 THEN
return true
ELSE
return false
END
Run Code Online (Sandbox Code Playgroud)
将上述代码包装到Lua脚本中以确保其自动运行。如果此脚本返回true,则执行 API 调用。否则,什么也不做。