
php+redis完成令牌桶算法代码:
<?phpnamespace Api\Lib;/**
* 限流管制
*/class RateLimit{
private $minNum = 60; //单个用户每一分拜访数
private $dayNum = 10000; //单个用户天天总的拜访量
public function minLimit($uid)
{
$minNumKey = $uid . '_minNum';
$dayNumKey = $uid . '_dayNum';
$resMin = $this->getRedis($minNumKey, $this->minNum, 60);
$resDay = $this->getRedis($minNumKey, $this->minNum, 86400);
if (!$resMin['status'] || !$resDay['status']) {
exit($resMin['msg'] . $resDay['msg']);
}
}
public function getRedis($key, $initNum, $expire)
{
$nowtime = time();
$result = ['status' => true, 'msg' => ''];
$redisObj = $this->di->get('redis');
$redis->watch($key);
$limitVal = $redis->get($key);
if ($limitVal) {
$limitVal = json_decode($limitVal, true);
$newNum = min($initNum, ($limitVal['num'] - 1) + (($initNum / $expire) * ($nowtime - $limitVal['time'])));
if ($newNum > 0) {
$redisVal = json_encode(['num' => $newNum, 'time' => time()]);
} else {
return ['status' => false, 'msg' => '以后时辰令牌耗费完!'];
}
} else {
$redisVal = json_encode(['num' => $initNum, 'time' => time()]);
}
$redis->multi();
$redis->set($key, $redisVal);
$rob_result = $redis->exec();
if (!$rob_result) {
$result = ['status' => false, 'msg' => '拜访频率过多!'];
}
return $result;
}}代码要点:
一、起首界说规定
单个用户每一分钟拜访次数($minNum),单个用户天天总的拜访次数($dayNum),接口总的拜访次数等没有同的规定。
二、较量争论速度
该代码示例以秒为最小的工夫单元,速度=拜访次数/工夫($initNum / $expire)
三、每一次拜访后增补的令牌个数较量争论形式
猎取前次拜访的工夫即前次存入令牌的工夫,较量争论以后时辰与前次拜访的工夫差乘以速度就是这次需求增补的令牌个数,留意增补令牌后总的令牌个数不克不及年夜于初始化的令牌个数,以增补数以及初始化数的最小值为准。
四、顺序流程
第一次拜访时初始化令牌个数($minNum),存入Redis同时将以后的工夫戳存入以便较量争论下次需求增补的令牌个数。
第二次拜访时猎取残余的令牌个数,并增加本次应该增补的令牌个数,增补后若何令牌数>0则以后拜访是无效的能够拜访,不然令牌应用终了不成拜访。先增补令牌再判别令牌能否>0的缘由是因为另有速度这个概念即假如前次残余的令牌为0然而本次应该增补的令牌>1那末本次仍然能够拜访。
五、针对并发的解决
应用Redis的悲观锁机制。
更多相干常识,请存眷 PHP中文网!!
以上就是令牌桶算法若何应用php完成的具体内容,更多请存眷资源魔其它相干文章!
标签: php php教程 php故障解决 php使用问题 令牌桶算法
版权声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。
抱歉,评论功能暂时关闭!