成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Redis實際應用之限流

存儲 存儲軟件 Redis
首先讓我們先看一看系統架構設計中,為什么要做“限流”。不知道大家注意過沒有,比如雙11,剛過12點有些顧客的網頁或APP會顯示下單失敗的提示,有些就是被限流掉了。

[[394640]]

為什么要做限流

首先讓我們先看一看系統架構設計中,為什么要做“限流”。

旅游景點通常都會有最大的接待量,不可能無限制的放游客進入,比如故宮每天只賣八萬張票,超過八萬的游客,無法買票進入,因為如果超過八萬人,景點的工作人員可能就忙不過來,過于擁擠的景點也會影響游客的體驗和心情,并且還會有安全隱患;「只賣N張票,這就是一種限流的手段」。

軟件架構中的服務限流也是類似,也是當系統資源不夠的時候,已經不足以應對大量的請求,為了保證服務還能夠正常運行,那么按照規則,「系統會把多余的請求直接拒絕掉,以達到限流的效果」;

不知道大家注意過沒有,比如雙11,剛過12點有些顧客的網頁或APP會顯示下單失敗的提示,有些就是被限流掉了。

常見的限流算法

計數法

顧名思義就是來一個,記錄一個,比如我1分鐘只能處理1000個請求,那么我們就可以設置一個計數器,來一個請求就incr+1,當1分鐘之內的數量大于等于1000之后不處理了即可,偽代碼如下

  1. $redis = new Redis(); 
  2. $redis->connect('127.0.0.1', 6379); 
  3. $rate_limit = 1000;  //限制個數 
  4. $rate_seconds = 60;  //限制時間 
  5. $redis_key = "redis_limit"
  6. $count = $redis->get($redis_key); 
  7. if ($count >= $rate_limit){  //判斷60秒內請求個數是否已經達到上限 
  8.     //直接返回,不處理請求 
  9.     return 
  10. $redis->incr($redis_key, 1);//請求計數 
  11. $redis->expire($redis, $rate_seconds); //設置過期時間 60s 
  12. //to do  業務邏輯處理....... 

這種計數方式比較簡單快捷,但是有很大的缺點,因為請求的訪問不一定是很平穩的,如果0:59過來了1000個請求,1:01已經是下一個窗口,又過來了1000個請求,但實際上三秒內來了2000個請求,已經超過我們的限流上限了。所以這種方法是不推薦的。

滑動窗口算法

還拿上面的例子,一分鐘分6份,每份10秒;每過10秒鐘,我們的時間窗口就會往右滑動一格,每個格子都有獨立的計數器,我們每次都計算時間窗口內的數量,可以解決計數器法中的問題,而且當滑動窗口的格子越多,那么限流的統計就會越精確。具體可以參考下圖,看圖比較清晰

偽代碼實現如下

  1. function api_limit($scene,  $period, $maxCount){ 
  2.     $redis = new Redis(); 
  3.     $redis->connect('127.0.0.1', 6379); 
  4.     $key = sprintf('hist:%s', $scene); //限流場景唯一標識 
  5.     $now = msectime();   // 毫秒時間戳,這樣更精確 
  6.     $pipe=$redis->multi(Redis::PIPELINE); //使用管道提升性能 
  7.     $pipe->zadd($key, $now, $now); //value 和 score 都使用毫秒時間戳 
  8.     $pipe->zremrangebyscore($key, 0, $now - $period); //移除時間窗口之前的行為記錄,剩下的都是時間窗口內的 
  9.     $pipe->zcard($key);  //獲取窗口內的行為數量 
  10.     $pipe->expire($key, $period/1000 + 1);  //多加一秒過期時間 
  11.     $replies = $pipe->exec(); 
  12.     return $replies[2] <= $maxCount;  //$replies[2]為zcard返回的個數  如果zcard結果大于maxCount,則不處理結果 
  13.  
  14. for ($i=0; $i<20; $i++){  //測試限流是否實現代碼 
  15.     var_dump(isActionAllowed("uniq_scene", 60*1000, 5)); //執行可以發現只有前5次是通過的 
  16.  
  17. //返回當前的毫秒時間戳 
  18. function msectime() { 
  19.     list($msec, $sec) = explode(' ', microtime()); 
  20.     $msectime = (float)sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000); 
  21.     return $msectime; 
  22.  } 

這段代碼還是略顯復雜,需要讀者花一定的時間好好啃。它的整體思路就是:每一個行為到來時,都維護一次時間窗口。將時間窗口外的記錄全部清理掉,只保留窗口內的記錄。

因為這幾個連續的 Redis 操作都是針對同一個 key 的,使用 pipeline 可以顯著提升Redis 存取效率。「但這種方案也有缺點,因為它要記錄時間窗口內所有的行為記錄,如果這個量很大,比如限定 60s 內操作不得超過 100w 次這樣的參數,它是不適合做這樣的限流的,因為會消耗大量的存儲空間」。

 

后面還有漏桶算法和令牌桶算法,由于各自的實現比較復雜,所以準備各自新開一篇文章單獨描述

 

責任編輯:武曉燕 來源: 程序員小飯
相關推薦

2010-03-01 15:51:01

WCF限流

2022-12-12 09:07:06

Redis并發限流

2022-05-16 13:46:38

Redis高可用Sentinel

2009-07-15 09:59:36

MyEclipse使用

2009-07-15 09:59:36

MyEclipse使用

2010-06-10 13:47:16

2013-12-21 20:03:34

SDN應用應用交付SDN

2010-07-06 15:46:41

UDP協議

2011-06-03 09:25:13

netstatDHCP

2010-06-04 10:01:26

Hadoop安裝

2009-12-18 10:58:17

Linux應用程序

2010-03-09 19:07:01

Python語法

2011-08-10 10:23:20

iPhoneArchivingNSCoder

2014-07-10 10:43:49

zabbix主從監控

2017-01-18 08:41:22

大數據畫像建設

2017-02-05 18:36:36

大數據Docker容器

2009-02-24 09:04:53

數據庫工程師 評選

2011-08-16 19:02:23

iPhone開發繪圖

2013-12-21 19:58:32

SDN應用資源管理平臺SDN

2010-08-02 13:05:01

DB2應用
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 夜夜草 | 毛片链接| 北条麻妃一区二区三区在线观看 | 久久久久久亚洲国产精品 | 欧美区日韩区 | 亚洲第一av| 免费在线观看av网址 | 99视频免费在线 | 成人性视频在线播放 | 国产99视频精品免视看9 | 成人在线视频免费看 | 中文字幕 欧美 日韩 | 一区二区三区在线免费观看 | 久久lu| 午夜精品一区二区三区在线观看 | 91视频进入| 91精品国产91综合久久蜜臀 | 久久精品久久久久久 | 久久99精品久久久 | 天天看天天摸天天操 | 欧美一区二区三区 | 国产一区二区三区视频免费观看 | 91麻豆精品国产91久久久久久 | 亚洲欧美一区二区三区在线 | 日韩精品免费播放 | 九九热在线免费视频 | 亚洲欧美综合 | 在线观看国产视频 | 国产一区二区三区 | 国产婷婷色一区二区三区 | 自拍偷拍亚洲一区 | 成人在线免费观看视频 | 91精品久久久久久久99 | 一区二区三区日韩 | 国产女人精品视频 | 亚洲国产精品99久久久久久久久 | 人人99| 欧美福利精品 | 亚洲日日操| 免费毛片网 | 久久精品国产亚洲夜色av网站 |