ホームページ バックエンド開発 PHPチュートリアル Redis に基づくトラフィック制御を実装するためにトークン バケット アルゴリズムを使用して PHP の関連コンテンツを説明する

Redis に基づくトラフィック制御を実装するためにトークン バケット アルゴリズムを使用して PHP の関連コンテンツを説明する

Jun 08, 2018 pm 03:34 PM
php redis

この記事では、redis に基づく PHP を紹介し、トークン バケット アルゴリズムを使用してアクセス トラフィックを制御します。誰でも学習して使用できる、アルゴリズムの完全な説明とデモンストレーションの例を提供します。

国内の長期休暇や重要な祭りがある場合、国内の景勝地や地下鉄は混雑し、混雑が予想され、場合によっては交通規制が行われ、乗車数が制限されます。エリア内の人数が減少すると、一定値に達すると入場が許可されます。

例:

エリア内で許可される最大人数は MM
エリア内の現在の人数はN
人が入場するたびに、N 1N = Mの場合、入場は許可されません
人が退出するたびに、N-1N
もちろん、サーバーを追加して圧力を分散することもできます。まず、サーバーの追加には構成にもある程度の時間がかかります。また、特定のアクティビティのためにサーバーが追加された場合、これらのサーバー リソースが無駄になります。活動が終わった後。

したがって、最初に

current Limiting を使用して、ビジネスの種類に応じてサーバーの負荷を軽減できます。 景勝地の交通制限とは異なり、

訪問からシステムの終了までの時間は非常に短いため、各訪問の平均時間を把握し、最大時間を設定するだけで済みます。同時訪問者数。

トークンバケットアルゴリズム
1. まず、トークンバケットがあり、トークンはバケットに格納されます。最初は、トークンバケット内のトークンはいっぱいです(トークンの数)。バケット内の数量はサーバーの状況に応じて設定できます)。

2. 各訪問はバケットからトークンを取得します。バケット内のトークンが 0 の場合、それ以上の訪問は許可されません。

3. 時々、バケットがトークンでいっぱいになるまでトークンを追加します。 (実際の状況に応じて、間隔をあけて複数のトークンを投入することも、トークン バケットを直接埋めることもできます)

redis

のキューをトークン バケット コンテナとして使用できます。

lPush (エンキュー)、rPop (デキュー) を使用して、トークンの追加および消費操作を実装します。
TrafficShaper.class.php

<?php/**
 * PHP基于Redis使用令牌桶算法实现流量控制
 * Date:    2018-02-23
 * Author:  fdipzone
 * Version: 1.0
 *
 * Descripton:
 * php基于Redis使用令牌桶算法实现流量控制,使用redis的队列作为令牌桶容器,入队(lPush)出队(rPop)作为令牌的加入与消耗操作。
 *
 * Func:
 * public  add     加入令牌
 * public  get     获取令牌
 * public  reset   重设令牌桶
 * private connect 创建redis连接
 */class TrafficShaper{ // class start

    private $_config; // redis设定
    private $_redis;  // redis对象
    private $_queue;  // 令牌桶
    private $_max;    // 最大令牌数

    /**
     * 初始化
     * @param Array $config redis连接设定
     */
    public function __construct($config, $queue, $max){
        $this->_config = $config;        $this->_queue = $queue;        $this->_max = $max;        $this->_redis = $this->connect();
    }    /**
     * 加入令牌
     * @param  Int $num 加入的令牌数量
     * @return Int 加入的数量
     */
    public function add($num=0){

        // 当前剩余令牌数
        $curnum = intval($this->_redis->lSize($this->_queue));        // 最大令牌数
        $maxnum = intval($this->_max);        // 计算最大可加入的令牌数量,不能超过最大令牌数
        $num = $maxnum>=$curnum+$num? $num : $maxnum-$curnum;        // 加入令牌
        if($num>0){            $token = array_fill(0, $num, 1);            $this->_redis->lPush($this->_queue, ...$token);            return $num;
        }        return 0;

    }    /**
     * 获取令牌
     * @return Boolean
     */
    public function get(){
        return $this->_redis->rPop($this->_queue)? true : false;
    }    /**
     * 重设令牌桶,填满令牌
     */
    public function reset(){
        $this->_redis->delete($this->_queue);        $this->add($this->_max);
    }    /**
     * 创建redis连接
     * @return Link
     */
    private function connect(){
        try{            $redis = new Redis();            $redis->connect($this->_config[&#39;host&#39;],$this->_config[&#39;port&#39;],$this->_config[&#39;timeout&#39;],$this->_config[&#39;reserved&#39;],$this->_config[&#39;retry_interval&#39;]);            if(empty($this->_config[&#39;auth&#39;])){                $redis->auth($this->_config[&#39;auth&#39;]);
            }            $redis->select($this->_config[&#39;index&#39;]);
        }catch(RedisException $e){            throw new Exception($e->getMessage());            return false;
        }        return $redis;
    }


} // class end?>
ログイン後にコピー

デモ:

<?php/**
 * 演示令牌加入与消耗
 */require &#39;TrafficShaper.class.php&#39;;// redis连接设定$config = array(    &#39;host&#39; => &#39;localhost&#39;,    &#39;port&#39; => 6379,    &#39;index&#39; => 0,    &#39;auth&#39; => &#39;&#39;,    &#39;timeout&#39; => 1,    &#39;reserved&#39; => NULL,    &#39;retry_interval&#39; => 100,
);// 令牌桶容器$queue = &#39;mycontainer&#39;;// 最大令牌数$max = 5;// 创建TrafficShaper对象$oTrafficShaper = new TrafficShaper($config, $queue, $max);// 重设令牌桶,填满令牌$oTrafficShaper->reset();// 循环获取令牌,令牌桶内只有5个令牌,因此最后3次获取失败for($i=0; $i<8; $i++){
    var_dump($oTrafficShaper->get());
}// 加入10个令牌,最大令牌为5,因此只能加入5个$add_num = $oTrafficShaper->add(10);

var_dump($add_num);// 循环获取令牌,令牌桶内只有5个令牌,因此最后1次获取失败for($i=0; $i<6; $i++){
    var_dump($oTrafficShaper->get());
}?>
ログイン後にコピー
出力:

boolean trueboolean trueboolean trueboolean trueboolean trueboolean falseboolean falseboolean falseint 5boolean trueboolean trueboolean trueboolean trueboolean trueboolean false
ログイン後にコピー

定期的にトークンに参加するアルゴリズム

定期的にトークンに参加する場合、crontab を使用して実装し、毎分呼び出します。 add メソッドはいくつかのトークンを追加します。 crontab の使用方法については、「Linux crontab スケジュールタスク実行コマンドの形式と詳細な例」を参照してください。

トークンバケット内のトークンが消費された場合、crontab の最小実行間隔は 1 分です。最初の数秒間はトークンが取得できず、残りの数十秒間はトークンを取得できず、ユーザーは長時間待たされてしまいます。

トークンを追加するアルゴリズムを最適化し、1 分以内に数秒ごとに複数のトークンを追加することで、1 分以内に毎回トークンを取得できるようになります。

crontab によって呼び出されるトークン追加プログラムは次のとおりで、1 秒あたり 3 つのトークンを自動的に追加します。

<?php/**
 * 定时任务加入令牌
 */require &#39;TrafficShaper.class.php&#39;;// redis连接设定$config = array(    &#39;host&#39; => &#39;localhost&#39;,    &#39;port&#39; => 6379,    &#39;index&#39; => 0,    &#39;auth&#39; => &#39;&#39;,    &#39;timeout&#39; => 1,    &#39;reserved&#39; => NULL,    &#39;retry_interval&#39; => 100,
);// 令牌桶容器$queue = &#39;mycontainer&#39;;// 最大令牌数$max = 10;// 每次时间间隔加入的令牌数$token_num = 3;// 时间间隔,最好是能被60整除的数,保证覆盖每一分钟内所有的时间$time_step = 1;// 执行次数$exec_num = (int)(60/$time_step);// 创建TrafficShaper对象$oTrafficShaper = new TrafficShaper($config, $queue, $max);for($i=0; $i<$exec_num; $i++){    $add_num = $oTrafficShaper->add($token_num);    echo &#39;[&#39;.date(&#39;Y-m-d H:i:s&#39;).&#39;] add token num:&#39;.$add_num.PHP_EOL;
    sleep($time_step);
}?>
ログイン後にコピー
シミュレーション消費プログラムは次のとおりで、1 秒あたり 2 ~ 8 個のトークンを消費します。

<?php/**
 * 模拟用户访问消耗令牌,每段时间间隔消耗若干令牌
 */require &#39;TrafficShaper.class.php&#39;;// redis连接设定$config = array(    &#39;host&#39; => &#39;localhost&#39;,    &#39;port&#39; => 6379,    &#39;index&#39; => 0,    &#39;auth&#39; => &#39;&#39;,    &#39;timeout&#39; => 1,    &#39;reserved&#39; => NULL,    &#39;retry_interval&#39; => 100,
);// 令牌桶容器$queue = &#39;mycontainer&#39;;// 最大令牌数$max = 10;// 每次时间间隔随机消耗的令牌数量范围$consume_token_range = array(2, 8);// 时间间隔$time_step = 1;// 创建TrafficShaper对象$oTrafficShaper = new TrafficShaper($config, $queue, $max);// 重设令牌桶,填满令牌$oTrafficShaper->reset();// 执行令牌消耗while(true){    $consume_num = mt_rand($consume_token_range[0], $consume_token_range[1]);    for($i=0; $i<$consume_num; $i++){        $status = $oTrafficShaper->get();        echo &#39;[&#39;.date(&#39;Y-m-d H:i:s&#39;).&#39;] consume token:&#39;.($status? &#39;true&#39; : &#39;false&#39;).PHP_EOL;
    }
    sleep($time_step);
}?>
ログイン後にコピー
デモ

スケジュールされたタスクを設定し、1分ごとに実行します

* * * * * php /程序的路径/cron_add.php >> /tmp/cron_add.log
ログイン後にコピー

実行シミュレーションの消費

php consume_demo.php
ログイン後にコピー

実行結果:

[2018-02-23 11:42:57] consume token:true[2018-02-23 11:42:57] consume token:true[2018-02-23 11:42:57] consume token:true[2018-02-23 11:42:57] consume token:true[2018-02-23 11:42:57] consume token:true[2018-02-23 11:42:57] consume token:true[2018-02-23 11:42:57] consume token:true[2018-02-23 11:42:58] consume token:true[2018-02-23 11:42:58] consume token:true[2018-02-23 11:42:58] consume token:true[2018-02-23 11:42:58] consume token:true[2018-02-23 11:42:58] consume token:true[2018-02-23 11:42:58] consume token:true[2018-02-23 11:42:58] consume token:false[2018-02-23 11:42:59] consume token:true[2018-02-23 11:42:59] consume token:true[2018-02-23 11:42:59] consume token:true[2018-02-23 11:42:59] consume token:false[2018-02-23 11:42:59] consume token:false[2018-02-23 11:42:59] consume token:false[2018-02-23 11:42:59] consume token:false[2018-02-23 11:43:00] consume token:true[2018-02-23 11:43:00] consume token:true[2018-02-23 11:43:00] consume token:true[2018-02-23 11:43:00] consume token:false[2018-02-23 11:43:00] consume token:false
ログイン後にコピー

最初はトークンバケットがいっぱいなので(トークンの最大数は10)、最初の10回まではトークンを取得できますが、10回以降は消費トークンが大きくなります。参加トークンの枚数を超えるとアクセスが制限されます。

この記事では、トークン バケット アルゴリズムを使用して Redis に基づいたトラフィック制御を実装する PHP の関連コンテンツについて説明します。その他の関連コンテンツについては、PHP の中国語 Web サイトを参照してください。

関連する推奨事項:

PHP を使用してロゴ付きの QR コード クラスを作成する方法



mysql によるテーブル パーティションの再構築と保持の詳細な説明data メソッド


php json_encode がオブジェクトのプライベート属性をサポートしていないことについての説明

以上がRedis に基づくトラフィック制御を実装するためにトークン バケット アルゴリズムを使用して PHP の関連コンテンツを説明するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Redisクラスターモードの構築方法 Redisクラスターモードの構築方法 Apr 10, 2025 pm 10:15 PM

Redisクラスターモードは、シャードを介してRedisインスタンスを複数のサーバーに展開し、スケーラビリティと可用性を向上させます。構造の手順は次のとおりです。異なるポートで奇妙なRedisインスタンスを作成します。 3つのセンチネルインスタンスを作成し、Redisインスタンスを監視し、フェールオーバーを監視します。 Sentinel構成ファイルを構成し、Redisインスタンス情報とフェールオーバー設定の監視を追加します。 Redisインスタンス構成ファイルを構成し、クラスターモードを有効にし、クラスター情報ファイルパスを指定します。各Redisインスタンスの情報を含むnodes.confファイルを作成します。クラスターを起動し、CREATEコマンドを実行してクラスターを作成し、レプリカの数を指定します。クラスターにログインしてクラスター情報コマンドを実行して、クラスターステータスを確認します。作る

PHPの未来:適応と革新 PHPの未来:適応と革新 Apr 11, 2025 am 12:01 AM

PHPの将来は、新しいテクノロジーの傾向に適応し、革新的な機能を導入することで達成されます。1)クラウドコンピューティング、コンテナ化、マイクロサービスアーキテクチャに適応し、DockerとKubernetesをサポートします。 2)パフォーマンスとデータ処理の効率を改善するために、JITコンパイラと列挙タイプを導入します。 3)パフォーマンスを継続的に最適化し、ベストプラクティスを促進します。

Redisデータをクリアする方法 Redisデータをクリアする方法 Apr 10, 2025 pm 10:06 PM

Redisデータをクリアする方法:Flushallコマンドを使用して、すべての重要な値をクリアします。 FlushDBコマンドを使用して、現在選択されているデータベースのキー値をクリアします。 [選択]を使用してデータベースを切り替え、FlushDBを使用して複数のデータベースをクリアします。 DELコマンドを使用して、特定のキーを削除します。 Redis-CLIツールを使用してデータをクリアします。

PHP対Python:違いを理解します PHP対Python:違いを理解します Apr 11, 2025 am 12:15 AM

PHP and Python each have their own advantages, and the choice should be based on project requirements. 1.PHPは、シンプルな構文と高い実行効率を備えたWeb開発に適しています。 2。Pythonは、簡潔な構文とリッチライブラリを備えたデータサイエンスと機械学習に適しています。

PHPの現在のステータス:Web開発動向を見てください PHPの現在のステータス:Web開発動向を見てください Apr 13, 2025 am 12:20 AM

PHPは、現代のWeb開発、特にコンテンツ管理とeコマースプラットフォームで依然として重要です。 1)PHPには、LaravelやSymfonyなどの豊富なエコシステムと強力なフレームワークサポートがあります。 2)パフォーマンスの最適化は、Opcacheとnginxを通じて達成できます。 3)PHP8.0は、パフォーマンスを改善するためにJITコンパイラを導入します。 4)クラウドネイティブアプリケーションは、DockerおよびKubernetesを介して展開され、柔軟性とスケーラビリティを向上させます。

PHPとPython:2つの一般的なプログラミング言語を比較します PHPとPython:2つの一般的なプログラミング言語を比較します Apr 14, 2025 am 12:13 AM

PHPとPythonにはそれぞれ独自の利点があり、プロジェクトの要件に従って選択します。 1.PHPは、特にWebサイトの迅速な開発とメンテナンスに適しています。 2。Pythonは、データサイエンス、機械学習、人工知能に適しており、簡潔な構文を備えており、初心者に適しています。

Redisキューの読み方 Redisキューの読み方 Apr 10, 2025 pm 10:12 PM

Redisのキューを読むには、キュー名を取得し、LPOPコマンドを使用して要素を読み、空のキューを処理する必要があります。特定の手順は次のとおりです。キュー名を取得します:「キュー:キュー」などの「キュー:」のプレフィックスで名前を付けます。 LPOPコマンドを使用します。キューのヘッドから要素を排出し、LPOP Queue:My-Queueなどの値を返します。空のキューの処理:キューが空の場合、LPOPはnilを返し、要素を読む前にキューが存在するかどうかを確認できます。

PHP:多くのウェブサイトの基礎 PHP:多くのウェブサイトの基礎 Apr 13, 2025 am 12:07 AM

PHPが多くのWebサイトよりも優先テクノロジースタックである理由には、その使いやすさ、強力なコミュニティサポート、広範な使用が含まれます。 1)初心者に適した学習と使用が簡単です。 2)巨大な開発者コミュニティと豊富なリソースを持っています。 3)WordPress、Drupal、その他のプラットフォームで広く使用されています。 4)Webサーバーとしっかりと統合して、開発の展開を簡素化します。

See all articles