02-概览
6.1 概览
4.2.2节实现了访问频率限制功能,可以限制一个IP地址在1分钟内最多只能访问100次:
$isKeyExists = EXISTS rate.limiting:$IP
if $isKeyExists is 1
$times = INCR rate.limiting:$IP
if $times > 100
print 访问频率超过了限制,请稍后再试。
exit
else
MULTIr
INCR rate.limiting:$IP
EXPIRE $keyName, 60
EXEC
当时提到上面的代码会出现竞态条件,解决方法是用 WATCH 命令检测 rate.limiting:$IP 键的变动,但是这样做比较麻烦,而且还需要判断事务是否因为键被改动而没有执行。除此之外这段代码在不使用管道的情况下最多要向Redis请求5条命令,在网络传输上会浪费很多时间。
我们这时最希望的就是Redis直接提供一个“ RATELIMITING ”命令用来实现访问频率限制功能,这个命令只需要我们提供键名、时间限制和在时间限制内最多访问的次数三个参数就可以直接返回访问频率是否超限。就像这样。
if RATELIMITING rate.limiting:$IP, 60, 100
print 访问频率超过了限制,请稍后再试。
else
# 没有超限,显示博客内容
这种方式不仅代码简单、没有竞态条件(Redis的命令都是原子的),而且减少了通过网络发送和接收命令的传输开销。然而可惜的是Redis并没有提供这个命令,不过我们可以使用Redis脚本功能自己定义新的命令。