$rate, 'lastRefillTime' => time() ]; Cache::set($bucketKey, $bucketData, 1); } $currentTime = time(); $timePassed = $currentTime - $bucketData['lastRefillTime']; $tokensToAdd = $timePassed * $rate; $tokensToAdd = min($tokensToAdd, $rate); $bucketData['tokens'] += $tokensToAdd; $bucketData['lastRefillTime'] = $currentTime; if ($bucketData['tokens'] <= 0) { return false; } $bucketData['tokens']--; Cache::set($bucketKey, $bucketData, 1); return true; } /** * 令牌桶限流器 * @param string $name * @param int $rate * @param int $capacity * @return bool */ public static function BucketLimit(string $name, int $rate = 10, int $capacity = 100): bool { $bucketKey = self::RATE_LIMIT_BUCKET . $name; $bucketData = Cache::get($bucketKey); if (!$bucketData) { $bucketData = [ 'tokens' => $capacity, 'lastRefillTime' => time() ]; Cache::set($bucketKey, $bucketData); } $currentTime = time(); $elapsedTime = $currentTime - $bucketData['lastRefillTime']; $refillTokens = (int)($elapsedTime * $rate); $bucketData['tokens'] = min($bucketData['tokens'] + $refillTokens, $capacity); $bucketData['lastRefillTime'] = $currentTime; if ($bucketData['tokens'] <= 0) { return false; } $bucketData['tokens']--; Cache::set($bucketKey, $bucketData); return true; } }