How to implement the token bucket algorithm using php

Release: 2023-02-28 19:20:01
Original
3205 people have browsed it

How to implement the token bucket algorithm using php

php redis implements the token bucket algorithm code:

<?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;
    }}
Copy after login

Code points:

1. First define the rules

Single user There are different rules such as the number of visits per minute ($minNum), the total number of visits per day by a single user ($dayNum), the total number of visits to the interface, etc.

2. Calculate the rate

This code example uses seconds as the minimum time unit, rate = number of visits/time ($initNum / $expire)

3. Each time How to calculate the number of tokens added after a visit

Get the time of the last visit, that is, the time when the token was last stored. Calculate the time difference between the current time and the last visit multiplied by the rate to get the number that needs to be added this time. The number of tokens. Note that the total number of tokens after replenishing tokens cannot be greater than the initialized number of tokens. The minimum value of the replenished number and the initialized number shall prevail.

4. Program flow

Initialize the number of tokens ($minNum) during the first visit, store it in Redis and store the current timestamp in order to calculate the tokens that need to be supplemented next time. Number of cards.

Get the remaining number of tokens during the second visit, and add the number of tokens that should be supplemented this time. After the supplement, if the number of tokens > 0, the current visit is valid and accessible, otherwise The token is no longer accessible after use. The reason for replenishing tokens first and then judging whether the tokens are > 0 is because there is also the concept of rate. That is, if the remaining tokens last time were 0 but the tokens that should be replenished this time are > 1, then you can still access it this time.

5. For concurrency processing

Use Redis’s optimistic locking mechanism.

For more related knowledge, please pay attention to PHP Chinese website! !

The above is the detailed content of How to implement the token bucket algorithm using php. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template