基于Redis的单个IP一段时间限制
一、实现类
接口被刷攻击应该是很常见的情况,特别是与用户名密码相关的接口,赶紧补上ip一段时间访问限制的控制吧,基本原理也能用于抢购。
我们先看Redis有这样一个命令:
SETNX:将 key 的值设为 value ,当且仅当 key 不存在。
若给定的 key 已经存在,则 SETNX 不做任何动作。
SETNX 是『SET if Not eXists』(如果不存在,则 SET)的简写。
于是我们就可以使用这个命令完成ip限制,如图一所示:
图一 通过Redis来完成ip的限制工具类
我们看下这段代码,如果设置访问次数为0成功后,设置该Key的过期时间,同时自增该Key,最后完成是否达到限制的判断,这里SETNX除了设置还达到了部分分布式锁的作用,有且只有一个线程能够设置初始值,其他线程只会对该Key进行增加,需要注意的是next必须是大于Limit,在这里是非线程安全的,另外一种逻辑是可以考虑使用volatile来处理next来保证抢购。
那么,我们怎么使用呢,在这里我们使用到了切片。
二、注解与切片类的实现
我们先定义注解,定义分别为值,次数,持续时间,如图二所示
图二 注解类
最后我们看切片类的实现,这里有个地方需要处理的就是如果使用了代理,要获取x-forward-for,并且这个Header的值是这样的
x-forward-for:源ip,代理ip1,代理ip2……
我们接着看切片类的代码,如图三所示
图三 切片类的代码
最后我们使用以下这个注解,如图四,
图四 注解的使用
当30s访问超过2次,就会抛出访问过于频繁的异常了。