PHP를 사용하여 토큰 버킷 알고리즘을 구현하는 방법

풀어 주다: 2023-02-28 19:20:01
원래의
3206명이 탐색했습니다.

PHP를 사용하여 토큰 버킷 알고리즘을 구현하는 방법

php+redis는 토큰 버킷 알고리즘 코드를 구현합니다:

<?phpnamespace Api\Lib;/**
 * 限流控制
 */class RateLimit{
    private $minNum = 60; //单个用户每分访问数
    private $dayNum = 10000; //单个用户每天总的访问量

    public function minLimit($uid)
    {
        $minNumKey = $uid . &#39;_minNum&#39;;
        $dayNumKey = $uid . &#39;_dayNum&#39;;
        $resMin    = $this->getRedis($minNumKey, $this->minNum, 60);
        $resDay    = $this->getRedis($minNumKey, $this->minNum, 86400);
        if (!$resMin[&#39;status&#39;] || !$resDay[&#39;status&#39;]) {
            exit($resMin[&#39;msg&#39;] . $resDay[&#39;msg&#39;]);
        }
    }

    public function getRedis($key, $initNum, $expire)
    {
        $nowtime  = time();
        $result   = [&#39;status&#39; => true, &#39;msg&#39; => &#39;&#39;];
        $redisObj = $this->di->get(&#39;redis&#39;);
        $redis->watch($key);
        $limitVal = $redis->get($key);
        if ($limitVal) {
            $limitVal = json_decode($limitVal, true);
            $newNum   = min($initNum, ($limitVal[&#39;num&#39;] - 1) + (($initNum / $expire) * ($nowtime - $limitVal[&#39;time&#39;])));
            if ($newNum > 0) {
                $redisVal = json_encode([&#39;num&#39; => $newNum, &#39;time&#39; => time()]);
            } else {
                return [&#39;status&#39; => false, &#39;msg&#39; => &#39;当前时刻令牌消耗完!&#39;];
            }
        } else {
            $redisVal = json_encode([&#39;num&#39; => $initNum, &#39;time&#39; => time()]);
        }
        $redis->multi();
        $redis->set($key, $redisVal);
        $rob_result = $redis->exec();
        if (!$rob_result) {
            $result = [&#39;status&#39; => false, &#39;msg&#39; => &#39;访问频次过多!&#39;];
        }
        return $result;
    }}
로그인 후 복사

코드 포인트:

1 먼저 규칙을 정의합니다.

단일 사용자의 분당 방문 횟수($minNum), 총 방문 횟수 단일 사용자의 일일($dayNum ), 인터페이스에 대한 총 액세스 횟수 및 기타 다른 규칙입니다.

2. 계산 비율

이 코드 예제에서는 최소 시간 단위로 초를 사용합니다. 비율 = 방문 횟수/시간($initNum / $expire)

3. 각 방문 후 추가된 토큰 수 계산 방법

마지막 방문 시간, 즉 토큰이 마지막으로 저장된 시간을 구합니다. 현재 시간과 마지막 방문 사이의 시간 차이를 계산하고 여기에 비율을 곱하여 이번에 보충해야 하는 토큰 수를 구합니다. . 토큰 보충 후 총 토큰 수에 주의하세요. 초기화된 토큰 수보다 클 수 없으며, 보충 수와 초기화 수의 최소값이 적용됩니다.

4. 프로그램 흐름

첫 번째 방문 시 토큰 수($minNum)를 초기화하고 이를 Redis에 저장한 후 현재 타임스탬프를 저장하여 다음에 보충해야 하는 토큰 수를 계산합니다.

두 번째 방문에서 남은 토큰 수를 가져오고 이번에 보충해야 할 토큰 수를 추가합니다. 보충 후 토큰 수가 > 0이면 현재 방문이 유효하고 액세스 가능합니다. 토큰이 모두 사용되었습니다. 토큰을 먼저 보충한 후 토큰이 >0인지 판단하는 이유는 비율의 개념도 있기 때문입니다. 즉, 지난번에 남은 토큰이 0이었지만 이번에 보충해야 할 토큰이 >1인 경우입니다. , 이번에는 여전히 액세스할 수 있습니다.

5. 동시 처리를 위해

Redis의 낙관적 잠금 메커니즘을 사용하세요.

더 많은 관련 지식은 PHP 중국어 홈페이지를 주목해주세요! !

위 내용은 PHP를 사용하여 토큰 버킷 알고리즘을 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿