From 91a16d4454203048693e519899f670df50a8e047 Mon Sep 17 00:00:00 2001 From: Ying Date: Wed, 2 Aug 2023 18:18:21 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0IP=E9=99=90=E6=B5=81?= =?UTF-8?q?=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- extend/system/RateLimiter.php | 89 +++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 extend/system/RateLimiter.php diff --git a/extend/system/RateLimiter.php b/extend/system/RateLimiter.php new file mode 100644 index 0000000..78e2a51 --- /dev/null +++ b/extend/system/RateLimiter.php @@ -0,0 +1,89 @@ + $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; + } +} \ No newline at end of file