频控实现原理

一、概念

       频控:通过限制单位时间内可访问的次数,达到限流的目的。利用频控,可以用来限制访问某些服务接口的流量,防止服务器由于承受太大的访问量而崩溃。

二、实现

       频控都会指定一个特征,比如:来自同一个用户的请求、来自同一个IP的请求等。实际应用场景中为防止服务过载,经常会有比如:每个用户在1分钟之内只能请求10次,每个IP在1小时之内只能请求30次等等这样的频控限制。一般都利用缓存比如Redis来实现频控。

       比如限制每个用户(用$uid表示)在1分钟之内只允许有30次请求,那么我们首先想到Redis的实现方式是:

//第一步:以$uid为key,从0开始每次请求累加1进行计数
$count = redis->incr($uid);
//第二步:如果是第1次请求,那么设置该key的过期时间为60秒
if($count === 1){
    redis->expire($uid,60);
}
//第三步:判断当前请求是否已超过该key所限制的30次
if($count > 30){
    echo '已超过限制';
}

       乍一看没什么问题,但如果在第二步时设置过期时间失败了,那么将导致一个周期(1分钟)之后,计数器不会被重置清零,而是一直累加,这样频控将是一直超限的。

       为了确保在周期内,第1次累加和设置过期时间在一个事务中,可以利用SET方法。从Redis 2.6.12 开始,SET方法支持参数EX、PX、NX、XX。

//第一步:如果是第1次,设置过期时间后则会返回"OK",否则返回nil
$ret = redis->set($uid,1,array('EX'=>60,'NX'));
//第二步:如果不成功,说明本周期还未结束,计数累加
if(!$ret){
    $count = redis->incr($uid);
    //第三步:判断当前请求是否已超过该key所限制的30次
    if($count > 30){
        echo '已超过限制';
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值