Heim  >  Artikel  >  Backend-Entwicklung  >  So implementieren Sie den Token-Bucket-Algorithmus mit PHP

So implementieren Sie den Token-Bucket-Algorithmus mit PHP

尚
Original
2020-04-25 11:26:463142Durchsuche

So implementieren Sie den Token-Bucket-Algorithmus mit PHP

PHP+Redis-Implementierung des Token-Bucket-Algorithmus-Codes:

<?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;
    }}

Codepunkte:

1. Definieren Sie zuerst die Regeln

Einzelne Regeln umfassen die Anzahl der Benutzerbesuche pro Minute ($minNum), die Gesamtzahl der Besuche pro Tag durch einen einzelnen Benutzer ($dayNum), die Gesamtzahl der Besuche der Schnittstelle usw.

2. Berechnungsrate

In diesem Codebeispiel werden Sekunden als Mindestzeiteinheit verwendet, Rate = Anzahl der Besuche/Zeit ($initNum / $expire)

3 Zeit Berechnungsmethode für die Anzahl der nach einem Besuch hinzugefügten Token

Ermitteln Sie die Zeit des letzten Besuchs, d. h. die Zeit, zu der der Token zuletzt eingezahlt wurde, multipliziert durch die Rate, die dieses Mal hinzugefügt werden muss. Beachten Sie, dass die Gesamtzahl der Token nach dem Auffüllen nicht größer sein darf als der Mindestwert der aufgefüllten Anzahl Die Nummer hat Vorrang.

4. Programmablauf

Anzahl der Token ($minNum) beim ersten Besuch initialisieren, in Redis speichern und den aktuellen Zeitstempel speichern, um die zu ergänzenden Token zu berechnen nächstes Mal Anzahl der Karten.

Erhalten Sie die verbleibende Anzahl an Token beim zweiten Besuch und fügen Sie die Anzahl an Token hinzu, die dieses Mal ergänzt werden sollen. Wenn die Anzahl der Token nach der Ergänzung > 0 ist, ist der aktuelle Besuch gültig und zugänglich Nach der Nutzung ist der Token nicht mehr zugänglich. Der Grund dafür, zuerst die Token aufzufüllen und dann zu beurteilen, ob die Token > 0 sind, liegt darin, dass es auch das Konzept der Rate gibt. Das heißt, wenn die verbleibenden Token beim letzten Mal 0 waren, aber die Token, die dieses Mal wieder aufgefüllt werden sollten, dann > 1 sind Sie können dieses Mal immer noch darauf zugreifen.

5. Parallelitätsverarbeitung

Verwenden Sie den optimistischen Sperrmechanismus von Redis.

Weitere Informationen zu diesem Thema finden Sie auf der chinesischen PHP-Website! !

Das obige ist der detaillierte Inhalt vonSo implementieren Sie den Token-Bucket-Algorithmus mit PHP. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn