高并发下漏洞桶限流设计方案 - Redis

背景

在咱们作社区的时候,常常会出现发水帖的同窗。对于这种恶意刷帖的,咱们的运营同窗非常头疼,并且这种还不能在网关进行ip之类的过滤,只能基于单个单个用户进行处理,咱们常常策略就是:每分钟发帖次数不能超过2个,超事后就关小黑屋10分钟。redis

出现场景

  1. 上面讲的发帖的防刷机制。
  2. 广告流量的防刷。
  3. 接口请求失败进行熔断机制处理。
  4. ......

解决方案

对于这种“黑恶”请求,咱们必需要作到是关小黑屋,固然有的系统架构比较大的,在网关层面就已经进行关了,咱们这里是会在业务层来作,由于咱业务不是很大,固然同窗们也能够把这个移植到网关层,这样不用穿透到咱们业务侧,最少可以减小咱们机房内部网络流量。bash

流程图

流程说明

  1. 接口发起请求,服务端获取这个接口用户惟一标识(用户id,电话号码...).
  2. 判断该用户是否被锁住,若是锁住就直接返回错误码。
  3. 未锁住就将该请求标记,亦或者叠加(叠加有坑,往下面看)。
  4. 进行计算当前用户在必定时间内是否超过咱们设置的阈值。若是未超过直接返回。
  5. 若是超过,那么就进行锁定,再返回,下次请求的时候再进行判断。

具体方案

以咱们场景为例子,使用Redis来作分布式锁和原子计数器网络

时间内叠加,判断叠加值是否超过阈值

这个方案,在不少人设计的时候,都会考虑,看起来也没有太大问题,主要流程是:架构

  1. 假设咱们使用Redis来进行原子计数,每次进来咱们进行incr操做,而且将咱们的key设置为一个阈值过时时间.
//将咱们用户请求量叠加1
$request_nums = Redis::incr('user:1:request:nums',1);
//第一次叠加,设置key的过时时间
if ($request_nums == 1){
    Redis::expire('user:1:request:nums',300);
}

if($request_nums > 10){
    //加入小黑屋,下次再进来就要锁定判断
}

...

复制代码
  1. 每次请求会优先进行叠加,而后在这个有效区间内,计算咱们的请求次数,若是请求次数超过阈值,那么关小黑屋,要是没有就继续走下去。

问题:咋一看是没有问题,每次计算都在个人区间内,可以保证一个区间内的请求量是没问题的,并且仍是要咱们Redis的原子计数器,可是这里有一个问题是,一个用户两个时间段内都没有问题,可是跨时间段这个点是没有考虑的。分布式

那么有办法解决这个时间推移问题形成时间段计算量不精准的问题吗?lua

答案是确定有,我接下来是使用了Redis的有序集合来作。spa

请求不进行时间段区分,直接写入有序集合

大体流程:设计

  1. 每次请求就写入有序集合里面,集合的sorce值是当前毫秒时间戳(防止秒出现重复),能够认为每一次请求就一个时间戳在里面。
  2. 从集合里面去掉10分钟之前全部的集合数据。而后计算出当前的集合里面数量
  3. 根据这个数量来与咱们阈值作大小判断,若是超过就锁住,不然继续走下去
//将咱们时间戳写入咱们redis的有序集合里面
 Redis::zadd('user:1:request:nums',1561456435,'1561456435.122');
//设置key的过时时间为10分钟
Redis::expire('user:1:request:nums',300);
//删除咱们10分钟之前的数据
Redis::ZREMRANGEBYSCORE('user:1:request:nums',0,1561456135);
//获取里面剩下请求个数
$request_nums=(int)Redis::zcard(self::TIMELINE_ELEVEL_KEY);
if($request_nums >= 10){
    //加入小黑屋,下次再进来就要锁定判断
}
...

复制代码

由于咱们不是单纯记录数值,而是会将请求时间记录下来,那么随着时间推移,咱们的请求数统计是不会断代的。code

总结

  1. 在开始的时候,我一直在想第一个方案的问题所在,后来在讨论方案时候,老是发现时间移动,数值应该是会更改,可在第一个方案内,咱们的请求量是不会更改,咱们时间段已经固化成数值了。
  2. 总体的方案设计咱们使用到的Redis的有序集合来作,固然有更好的方案欢迎你们来推荐哈,这个对于redis的读写压力很大的,可是做为临时的数据存储,这个场景仍是比较符合。
  3. 咱们redis的全部操做建议使用原子化来进行,这个可使用官方提供的lua脚原本将多个语句合并成一个语句,而且lua执行速率也是很高。

谢谢你们阅读!!!cdn

相关文章
相关标签/搜索