接口防刷通过Redis进行限制。
实现思路:
1、用户在访问接口的时候,获取用户的ip
$request -> ip();
2、把ip作为key,访问次数作为对应的值,每次访问接口累加访问次数即可。
【注意一个问题:key的有效期是1分钟,必须是第一次写入的时候 指定1分钟的有效期】
3、下一次访问的时候,判断是否超过100次,如果超过的,吧ip加入黑名单中半个小时。
【用的数据类型是有序集合】
4、用户再访问的时候,判断他的ip是否在黑名单中,如果在黑名单,就不允许访问
5、需要注意,我们只是吧这个ip放入黑名单半个小时。
【 用户ip进入黑名单的时间,只有半个小时,如果超过半个小时 需要从黑名单移除这个ip 】
一分钟统计ip访问次数,可能会存在的问题?
比如说我们在12:00:01的时候,访问1次,在12:00:59访问了98次,这样的话是没有到100次的,在12:00统计的数据,在12:01之前就过期了。
继续在12:01:01在去访问99次,也没有达到限制的100次。
这样的话,在12:00:59到12:01:01这三秒钟超过了100次。这样的话 限制就不存在意义了。
如何解决按分钟统计出现的问题?
一、分开统计访问次数:
1、把一分钟分为6段,每段分别统计访问次数
2、每次再算访问次数的时候,统计出当前的时间端的访问次数
3、在向前去前5段时间的访问次数,吧这6段时间加起来
4、判断是否超过我们的限制,如果超过加入黑名单
二、令牌桶
1、在redis中设置一个集合,集合中存在10个元素
2、客户端每次调用接口的时候,从集合中取出一个值
3、如果能够正常去到值,说明正常,允许访问
4、如果没有取到,说明限制令牌桶是空的,则不允许访问
5、每隔10s中给集合中添加10个元素 【 不是每次都写10个元素,而是把集合补够10个数字即可 】