php redis令牌桶,php+redis实现令牌桶限流

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); // redis watch 处理并发

$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;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值