亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 邏輯算法 > 正文

php 基于redis使用令牌桶算法實現流量控制

2020-03-22 18:58:26
字體:
來源:轉載
供稿:網友
本文介紹php基于redis,使用令牌桶算法,實現訪問流量的控制,提供完整算法說明及演示實例,方便大家學習使用。
每當國內長假期或重要節日時,國內的景區或地鐵都會人山人海,導致負載過大,部分則會采用限流措施,限制進入的人數,當區內人數降低到一定值,再允許進入。

例如:
區內最大允許人數為 M
區內當前人數為 N
每進入一個人,N+1,當N = M時,則不允許進入
每離開一個人,N-1,當N < M時,可允許進入
系統在運行過程中,如遇上某些活動,訪問的人數會在一瞬間內爆增,導致服務器瞬間壓力飆升,使系統超負荷工作。

當然我們可以增加服務器去分擔壓力,首先增加服務器也需要一定的時間去配置,而且因為某一個活動而增加服務器,活動結束后這些服務器資源就浪費了。

因此我們可以根據業務類型,先使用限流的方式去減輕服務器壓力。

與景區限流不同,系統的訪問到結束的時間非常短,因此我們只需要知道每個訪問持續的平均時間,設定最多同時訪問的人數即可。

令牌桶算法

1.首先設有一個令牌桶,桶內存放令牌,一開始令牌桶內的令牌是滿的(桶內令牌的數量可根據服務器情況設定)。

2.每次訪問從桶內取走一個令牌,當桶內令牌為0,則不允許再訪問。

3.每隔一段時間,再放入令牌,最多使桶內令牌滿額。(可以根據實際情況,每隔一段時間放入若干個令牌,或直接補滿令牌桶)

我們可以使用redis的隊列作為令牌桶容器使用,使用lPush(入隊),rPop(出隊),實現令牌加入與消耗的操作。

TrafficShaper.html' target='_blank'>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['host'],$this->_config['port'],$this->_config['timeout'],$this->_config['reserved'],$this->_config['retry_interval']);            if(empty($this->_config['auth'])){                $redis->auth($this->_config['auth']);            }            $redis->select($this->_config['index']);        }catch(RedisException $e){            throw new Exception($e->getMessage());            return false;        }        return $redis;    }} // class end?>

demo:

<?php/** * 演示令牌加入與消耗 */require 'TrafficShaper.class.php';// redis連接設定$config = array(    'host' => 'localhost',    'port' => 6379,    'index' => 0,    'auth' => '',    'timeout' => 1,    'reserved' => NULL,    'retry_interval' => 100,);// 令牌桶容器$queue = 'mycontainer';// 最大令牌數$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分鐘,如果令牌桶內的令牌在前幾秒就已經被消耗完,那么剩下的幾十秒時間內,都獲取不到令牌,導致用戶等待時間較長。

我們可以優化加入令牌的算法,改為一分鐘內每若干秒加入若干令牌,這樣可以保證一分鐘內每段時間都有機會能獲取到令牌。

crontab調用的加入令牌程序如下,每秒自動加入3個令牌。

<?php/** * 定時任務加入令牌 */require 'TrafficShaper.class.php';// redis連接設定$config = array(    'host' => 'localhost',    'port' => 6379,    'index' => 0,    'auth' => '',    'timeout' => 1,    'reserved' => NULL,    'retry_interval' => 100,);// 令牌桶容器$queue = 'mycontainer';// 最大令牌數$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 '['.date('Y-m-d H:i:s').'] add token num:'.$add_num.PHP_EOL;    sleep($time_step);}?>

模擬消耗程序如下,每秒消耗2-8個令牌。

<?php/** * 模擬用戶訪問消耗令牌,每段時間間隔消耗若干令牌 */require 'TrafficShaper.class.php';// redis連接設定$config = array(    'host' => 'localhost',    'port' => 6379,    'index' => 0,    'auth' => '',    'timeout' => 1,    'reserved' => NULL,    'retry_interval' => 100,);// 令牌桶容器$queue = 'mycontainer';// 最大令牌數$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 '['.date('Y-m-d H:i:s').'] consume token:'.($status? 'true' : 'false').PHP_EOL;    }    sleep($time_step);}?>

演示

設置定時任務,每分鐘執行一次

* * * * * 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次之后則會根據消耗的令牌大于加入令牌數時,限制訪問。
本文講解了php 基于redis使用令牌桶算法實現流量控制 ,更多相關內容請關注 。

相關推薦:

Redis主從同步,讀寫分離設置 的相關操作

介紹mysql重建表分區并保留數據的方法

PHP生成唯一RequestID類的相關內容

以上就是php 基于redis使用令牌桶算法實現流量控制的詳細內容,更多請關注 其它相關文章!

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
成人有码视频在线播放| 久久99久久99精品免观看粉嫩| 日韩国产欧美精品一区二区三区| 日韩av在线网站| 日本aⅴ大伊香蕉精品视频| 中文字幕日韩欧美在线| 国产网站欧美日韩免费精品在线观看| 亚洲日本成人网| 亚洲欧美日韩爽爽影院| 欧美大尺度在线观看| 红桃视频成人在线观看| 国产精品尤物福利片在线观看| 亚洲国产欧美一区二区三区同亚洲| 亚洲午夜女主播在线直播| 国语自产精品视频在线看| 久久久亚洲成人| 日韩二区三区在线| 亚洲国产成人精品电影| www国产精品com| 国产精品视频999| 欧美精品久久久久久久久久| 国产精品第一第二| 国产精品久久久久久久7电影| 97免费视频在线播放| 国产精品极品美女在线观看免费| 色噜噜国产精品视频一区二区| 久久全国免费视频| 色偷偷av一区二区三区| 国产亚洲成精品久久| 91探花福利精品国产自产在线| 国产成人免费av电影| 国产精品福利片| 精品日韩中文字幕| 欧美激情视频网站| 国产视频福利一区| 日韩精品高清在线观看| 一夜七次郎国产精品亚洲| 国产精品丝袜久久久久久不卡| 欧美日韩亚洲视频| 亚洲国产精品电影| 亚洲精品日韩激情在线电影| 亚洲黄页网在线观看| 国产精品美女久久| 国产综合在线视频| 国产美女精品视频| 亚洲桃花岛网站| 久久国内精品一国内精品| 亚洲欧美日韩天堂| 国产精品久久视频| 97精品视频在线播放| 国产精品狼人色视频一区| 久久久精品国产一区二区| 亚洲二区中文字幕| 日韩欧亚中文在线| 精品久久久久国产| 黄网动漫久久久| 91精品国产乱码久久久久久蜜臀| 日韩欧美在线视频免费观看| 91国产视频在线播放| 国产69精品久久久久99| 91地址最新发布| 亚洲色图第一页| 亚洲xxxx妇黄裸体| 国产精品视频在线播放| 26uuu国产精品视频| 狠狠久久五月精品中文字幕| 亚洲欧美成人在线| 欧美限制级电影在线观看| 亚洲aⅴ男人的天堂在线观看| 精品国产91久久久久久| 国产免费亚洲高清| 日本久久久久久久| 夜夜躁日日躁狠狠久久88av| 国产精品亚洲片夜色在线| 亚洲欧美在线一区二区| 亚洲国产精品美女| 色噜噜狠狠色综合网图区| 欧美丝袜美女中出在线| 亚洲人午夜精品| 国产精品视频久| 久久精品国产亚洲精品2020| 亚洲天堂成人在线| 亚洲精品美女久久久久| 热久久视久久精品18亚洲精品| 国产日韩中文字幕| 欧美成aaa人片在线观看蜜臀| 亚洲色图偷窥自拍| 久久免费精品日本久久中文字幕| 97在线看福利| 欧美肥婆姓交大片| 91欧美视频网站| 日韩中文第一页| 精品一区二区三区四区| 91在线国产电影| 亚洲成人a**站| 亚洲视频一区二区| 国产精品综合网站| 在线亚洲欧美视频| 国产精品久久久久久久久免费| 狠狠色狠色综合曰曰| 久久精品久久久久| 国产精品久久久久久久天堂| 4438全国成人免费| 亚洲黄页视频免费观看| 欧美极品在线视频| 日韩欧美国产中文字幕| 欧美成在线视频| 亚洲国产一区二区三区在线观看| 精品国产老师黑色丝袜高跟鞋| 2021久久精品国产99国产精品| 国产精品高精视频免费| 欧美亚洲激情视频| 久久久久久久一| 色妞色视频一区二区三区四区| 欧美一级淫片aaaaaaa视频| 成人精品aaaa网站| 国产精品久久久久久久久久久不卡| 欧美国产日韩在线| 日韩视频免费大全中文字幕| 中文字幕日韩在线视频| 蜜臀久久99精品久久久久久宅男| 国产精品美女www爽爽爽视频| 欧美一级视频在线观看| 亚洲天堂精品在线| 久久久久国色av免费观看性色| 精品国产91久久久久久老师| 欧美中文字幕精品| 97欧美精品一区二区三区| 日本精品久久中文字幕佐佐木| 96pao国产成视频永久免费| 久久久伊人欧美| 国产精品扒开腿做爽爽爽男男| 欧美日韩一区二区精品| 精品夜色国产国偷在线| 国内精品视频在线| 国产精品麻豆va在线播放| 亚洲人成毛片在线播放| 日韩亚洲成人av在线| 久久久久一本一区二区青青蜜月| 一区二区三区精品99久久| 91精品国产91久久| 亚洲欧美国产精品va在线观看| 欧美日韩国产区| 欧美精品一区二区三区国产精品| 欧美性高跟鞋xxxxhd| 欧美极度另类性三渗透| 欧美极品少妇xxxxⅹ喷水| 日韩精品免费在线视频观看| 成人女保姆的销魂服务| 国产一级揄自揄精品视频| 欧美日韩国产专区| 亚洲欧美在线第一页| 久久天天躁夜夜躁狠狠躁2022| 欧美成人免费大片| 亚洲人成电影网站色| 亚洲精品第一页| 成人福利网站在线观看11| 亚洲一级黄色片| 国产婷婷97碰碰久久人人蜜臀| 色哟哟网站入口亚洲精品| 欧美精品九九久久| 日韩成人在线免费观看| 热久久这里只有精品| 国产欧美精品在线|