public function checkLimit($cacheKey = '', $initNum = '', $expire = '', $retry = true) { $nowTime = time(); Redis::watch($cacheKey); $redisData = Redis::get($cacheKey); $limitData = $redisData ? json_decode($redisData, true) : ['num' => $initNum, 'time' => $nowTime]; // (单位时间访问频率 / 单位时间)*(当前时间 - 上次访问时间) = 上次请求至今可增加的访问次数 $addNum = intval(($initNum / $expire) * ($nowTime - $limitData['time'])); $newNum = min($initNum, (($limitData['num'] - 1) + $addNum)); Log::debug($cacheKey . '-剩余领牌次数:' . $newNum); if ($newNum <= 0) { return ['status' => false, 'msg' => '当前时刻令牌用完啦!']; } $limitData = json_encode(['num' => $newNum, 'time' => $nowTime]); Redis::multi(); Redis::set($cacheKey, $limitData); if (!Redis::exec()) { if (!$retry) { return ['status' => false, 'msg' => '访问频次过多!']; } else { //执行3次丢弃 for ($i = 0; $i < 3; $i++) { $aRet = self::_limit($cacheKey, $initNum, $expire, false); if (Arr::get($aRet, 'status', false)) { break; } if (Arr::get($aRet, 'msg') == '当前时刻令牌用完啦') { return $aRet; } } } } return ['status' => true, 'msg' => 'ok']; }
12-13
535
12-11
935
08-26
581