web安全

轉自網絡:http://www.cnblogs.com/zhengyun_ustc/p/rule1.html


Web開發工程師請閱讀下面的前端開發準則,這是第一部分,強調了過去幾年裏我們注意到的Web工程師務須處理的Web訪問安全基礎點。尤其是一些從傳統軟件開發轉入互聯網開發的工程師,請仔細閱讀,不要因爲忽視這些基礎點而製造一個又一個的漏洞或突發事件。


Web開發基本準則-55實錄-Web訪問安全


鄭昀 創建於2013年2月


鄭昀 最後更新於2013年10月14日


提綱:


Web訪問安全

緩存策略

存儲介質連接池

業務降級

併發請求的處理

關鍵詞:


Session Hijacking,XSS(Cross Site Scripting),SQLi(SQL Injection),CSRF(Cross-Site Request Forgery),FormHash,Rate Limits,平行權限


一,Web訪問安全

1.1.利用 FormHash 防 CSRF 和表單自動提交

  FormHash 指的是,通過在 Form 表單中構造一個隱藏的 input 元素,如:


  <input type="hidden" name="formhash" id="formhash" value="{FORMHASH}" />


  讓第三方難以僞造這個 input 的 value,藉此阻止網站外部隨意構造表單提交,即防CSRF。適合的業務場景有註冊、登錄、下單、秒殺、抽獎、積分換代金券等等。


  


1.1.1.康盛的做法

  康盛的產品如 Discuz 爲了防止灌水機發帖,FormHash 值是這麼計算的:


  它的計算函數爲 formhash() :


function formhash($specialadd = '') {      


global $_G;  


$hashadd = defined('IN_ADMINCP') ? 'Only For Discuz! Admin Control Panel' : '';   


return substr(md5(substr($_G['timestamp'], 0, -7)


        .$_G['username'].$_G['uid'].$_G['authkey']


        .$hashadd.$specialadd), 8, 8);


}


  首先,substr($_SGLOBAL['timestamp'], 0, -7),截取時間戳前3位(注意,康盛的這種做法允許 formhash 在一定的時間裏生效且不變,由於截取了時間戳的前3位,那麼有效期範圍是115天)。


  然後與用戶名、用戶UID、authkey、自定義的key等字符串連接。這裏的 authkey 是根據服務器端配置文件裏的 authkey 與客戶端 cookies 裏的 saltkey 鍵值連接後,md5 一下得到的,所以並不一定是固定值,取決於你怎麼向客戶端裏種 saltkey cookie 了(康盛選擇的是種一個 random(8) 的隨機值)。


  最後再做一次 md5,截取字符串的8位。


  服務器端用 submitcheck 函數進行驗證時,會再算一遍 formhash 來與客戶端提交的進行比對:$_POST['formhash'] == formhash()。


 


  康盛的 formhash 仿造機率很小,但也不見得是“不同表單不同隨機值”,所以可以在登錄後從康盛產品的網頁中得到一個 formhash 字符串,以及 cookies 裏的 saltkey 鍵值,然後構造表單並構造 HTTPRequest,提交即可,115天內有效。


  只能說康盛的做法簡單且有一定效果,適合作爲你起步的 Plan A 抵擋一陣子。


 


1.2.通過全局 Filter 檢測或過濾 XSS/SQLi/shell注入

  通過烏雲網的漏洞列表,我們可以發現 XSS注入[注1]/SQL 注入無處不在,各大廠商前赴後繼地犯錯。如果框架本身不能有效攔截或檢測,僅憑藉鐵打營盤流水兵的工程師自己的覺悟,恐怕朝不保夕。


 


  常見的誤區是,(因爲XSS漏洞很常見所以認爲)XSS沒什麼了不起的,不會起多大風浪。


  一個弱漏洞可能沒事兒,但是***者往往很有恆心毅力,如果被他們找到一連串的弱漏洞,再加上社會工程學的手段(請參考2013年,利用社工攻陷知乎後臺的安全案例),千里之堤就會毀於蟻穴。譬如,一個前臺的存儲型XSS漏洞,配合管理後臺的登錄帳號 Session Hijacking,就能輕易突入管理後臺。


  鄭昀推薦你閱讀以下安全案例以增進認識(有圖有真相):


2013年,豆瓣網存儲型XSS漏洞拿到用戶cookies,以及,豆瓣網發起同城活動插入XSS代碼等待管理員審覈時獲取管理員cookies;

2013年,天涯CSRF系列四:利用儲存XSS+僞CSRF進行蠕蟲***,“既然我們無法通過外部的鏈接來觸發CSRF,那麼我們可以利用存儲型XSS來觸發這個CSRF。在本域下發包,來源域是天涯的,自然不會攔截。正好在天涯博客日誌頁面發現一個儲存XSS的實例,那我們就來結合這個實例進行一次蠕蟲***。”;

2010年,優酷網分站SQL注射漏洞;2013年,優酷網分站之用sqlmap攻陷實錄;

2013年,Discuz! 後臺第三方插件上傳任意後綴文件拿shell。

  


  所以,首先,最好是在框架層面增加全局 Filter,對 HTTP Request 中的 $_GET/$_POST/$_COOKIE 進行字符串過濾,這種 Filter 將是強制性的。(出於防範CSRF(Cross-Site Request Forgery,跨站請求僞造)的考慮[注4],工程師儘量不要使用 $_REQUEST。)


  對於 PHP 來說,還可以在開發環境引入 laruence 的檢測 xss/sql/shell 注入的 PHP 擴展模塊:PHPTaint[注2]。


  其次,杜絕裸寫SQL。


  確保所有拼裝SQL參數的地方都有對參數進行校驗的預編譯環節,如使用 java.sql.PreparedStatement。


 


1.2.1.大的原則是:不要相信客戶端提交的數據

  要深刻理解XSS的原理,***代碼不一定(非要)在 <script></script> 中。


  所以,處理XSS注入的時候,不僅僅要轉義或刪除特殊的 HTML 標記和符號,如尖括號<>,如script,如iframe等,還需要過濾 JavaScript 事件所涉及的大量屬性,如下表所示:


屬性


當以下情況發生時,出現此事件


onabort


圖像加載被中斷


onblur


元素失去焦點


onchange


用戶改變域的內容


onclick


鼠標點擊某個對象


ondblclick


鼠標雙擊某個對象


onerror


當加載文檔或圖像時發生某個錯誤


onfocus


元素獲得焦點


onkeydown


某個鍵盤的鍵被按下


onkeypress


某個鍵盤的鍵被按下或按住


onkeyup


某個鍵盤的鍵被鬆開


onload


某個頁面或圖像被完成加載


onmousedown


某個鼠標按鍵被按下


onmousemove


鼠標被移動


onmouseout


鼠標從某元素移開


onmouseover


鼠標被移到某元素之上


onmouseup


某個鼠標按鍵被鬆開


onreset


重置按鈕被點擊


onresize


窗口或框架被調整尺寸


onselect


文本被選定


onsubmit


提交按鈕被點擊


onunload


用戶退出頁面


 表1 JavaScript事件屬性表


  否則,就可能出現下面這兩種的XSS漏洞實例:


例1:


  http://YourDomain.com/index?num=1%22+onmousemove%3Dalert%284%29+wb%3D%22


  %22就是單引號的轉義,%3D是等號,%28是左括號,%29是右括號。鼠標移動可觸發。


例2:


  訪問 http://YourDomain.com/;


  在頁眉的搜索輸入框中輸入關鍵詞:" wb=" (注:包含雙引號);


  在搜索結果頁面上,當鼠標移動時,就會彈出XSS種下的JS彈出框。


 


1.3.驗證碼服務不簡單

  圖片驗證碼或者答題驗證碼是爲了儘可能狙擊註冊機、秒殺器等非人類行爲,自然就成了***第一線的重要技術。


  


攻:提前收集驗證碼。適用場景:秒殺。在秒殺開始前就收集好驗證碼,從而提前準備好表單。


防:1)不同業務的驗證碼不得混用,登錄、註冊、抽獎、秒殺、下發短信驗證等各是各的。2)像秒殺這種與時間有關的業務場景,驗證碼就不允許提前生成。即使刻意構造出某個秒殺活動的圖片驗證碼URL訪問,也必須先判斷秒殺活動開始時間,阻止提前訪問。


 


攻:構造表單時使用過期 cookie。


驗證碼一般是瀏覽器提交 cookie 裏的 verifysession(一個標識本次驗證會話的 Hash 串)和手工輸入的驗證碼字符串 verifycode,服務器端按 F(verifysession)==verifycode 進行校驗。那麼秒殺器突破時,別用服務器之前響應的 Hash 串,一直用自己手中掌握的 verifysession 和 verifycode 提交,就可以突破了。即使這一組 verifysession 和 verifycode 在服務器端驗證後立即失效,也無所謂,多準備幾組數據,就拼誰的秒殺器併發提交快即可。


防:1)結合 FormHash 方法聯防。2)針對不同業務生成的驗證碼的過期時間可以單獨設定。可以讓某個業務的驗證碼圖片過期時間很短。


 


攻:OCR識別圖片驗證碼。


防:如果業務場景確實非常需要狙擊機器提交,那麼上答題驗證碼,但也因此有了“題庫有限”這個弱點。


 


攻:(既然題庫有限那麼)通過刷秒殺頁面來收集題目。然後人工快速回答,或者 OCR 識別問題內容,自動匹配答案。


防:FormHash 有一定作用,但對於“按鍵精靈”軟件錄製腳本(而不是機器構造表單),確實難以防範,第三方只要比真正的用戶響應快、提交快即可。


 


攻:答題時,構造表單使用過期題目。


原理類似於使用過期 cookie。如果本次秒殺商品對應的答題不是一對一鎖定的(即換其他題提交也可以),那麼也可以強制使用過期題目。


防:加Token。讓 Token 的生成與業務的具體場景有關。如一個 Token 由登錄用戶(以user id標識)和當前秒殺商品(以goods id標識)等關鍵信息生成。也是 FormHash 思路的延續。或者當前秒殺綁定題目,禁止使用其他題目答題。


 


攻:上面的措施都擋不住我。


防:攔人。對於黑名單用戶(手動加或自動識別),他能參與秒殺,但總是得到如下提示“系統繁忙:人太多了,休息一下,等等吧”。


 


其他電商的做法參考鄭昀的《對付秒殺器等惡意訪問行爲的簡單梳理》 [注6] 。


 


1.4.敏感信息存入 cookies 須防篡改

  電商應用有時候不可避免地存儲了一些敏感數據到客戶端,當然不希望被客戶端篡改。


  所以可以在 set-cookie 時加上防篡改驗證碼,或者不暴露原值直接對稱加密存儲。


  如:user_name=alex|bj95ef23cc6daecc475de


 


  防篡改驗證碼的生成規則可以很簡單:md5(cookieValue+key)或sha1(cookieValue+key),key可以是服務器端掌握的一個固定字符串,也可以很複雜(如LTPA示例[注7])。


 


1.5.IP地址防僞造

  有人會說可以通過 request.getHeader("X-FORWARDED-FOR") 獲得ip字符串,這個頭域簡稱 XFF 頭,只有在通過了 HTTP 代理或者負載均衡服務器時纔會添加該項。


  但一定要知道 XFF 頭僅僅是 HTTP Headers 中的一分子,那自然是可以隨意增刪改的。很多投票系統都有此漏洞,它們簡單地取 XFF 頭中的ip地址,設置爲客戶端來源地址,因此第三方可以僞造任何ip投票。


  所以規則一:不要輕信 HTTP Headers 裏的IP字段。


  


  還與客戶端到服務器端之間的路徑有關,所以工程師要關注生產環境裏你的 WebServer 前面到底掛的是什麼,Nginx 的 proxy_set_header 是怎麼配置的。


  幾種場景:1)F5->Nginx->WebServer;2)F5->WebServer;3)Client->CDN->Nginx。搞清楚場景和配置,拿到真正的 Remote Address,請參考鄭昀的《客戶端的IP地址僞造、CDN、反向代理、獲取的那些事兒[注8]》。


 


1.6.防 Session Hijacking

  當第三方以如下手法獲得了你的瀏覽器標識會話的字符串,那麼他也許能以你的身份冒名操作:


從訪問記錄裏獲得 URL 上攜帶的 Session Token;

利用 XSS 漏洞竊取 Cookie 裏存儲的 Session Token。

  所以,首先絕不在 URL 中傳遞 Session Token,除非走 HTTPS 通道。


  其次,需要多管齊下,1)cookie 裏的 Session Token,必須設定爲 httponly,禁止 JavaScript 讀取,以絕後患;2)如果服務器端還需要 cookie 裏存儲的用戶ID等信息,那麼 cookie 鍵值需要加簽名防篡改;3)根據客戶端的IP地址、User-Agent、Session和其他信息生成一個 UA Token,存儲在 cookie 裏;服務器端每次都會覈對這個 UA Token 是否正確,如果不正確則退出登錄。這樣,即使第三方拿到了你的 Session Token,也無法處於登錄狀態。


 


1.7.用 Robots.txt 限制住搜索引擎

  每一個對公網暴露的 Web 工程,上線之初理應配有 Robots.txt ,不僅僅是爲了SEO,而且要限制站點的某些目錄不允許抓取和收錄。


  內部站點的robots.txt 內容必須(MUST)是:


  User-agent: *


  Disallow: /


  不少瀏覽器都會向搜索引擎傳送訪問歷史,你以爲的內部隱祕訪問地址,可能早已被搜索引擎收錄了,所以對此絕不要掉以輕心。不要給***者借搜索“site:YourDomain.com”或“site:YourDomain.com URL:/YourPath” 遍歷內部站點的機會。


  鄭昀推薦你閱讀以下安全案例增進認識:


2012年,支付寶轉賬或交易結束後的結果頁面被 Google 收錄。

 


1.8.敏感信息的存儲和展示

  牢記一點,你的數據庫很有可能被***,我們要未雨綢繆,降低***後的危害!


  所以,敏感信息請加密存儲。


 


1.8.1.密碼的存儲

  首先,絕不能僅僅 MD5(password) 存儲,這樣等同於明文存儲。其次鐵律是,禁止明文存儲(登錄)密碼。


  最簡單的辦法是,隨機生成 SaltKey 並存儲,按 MD5(salt+MD5(password)) 存儲密碼。


  如果密碼需要二次分發(而不是重置密碼),請對稱加密存儲(應用程序掌管公鑰私鑰)。


 


1.8.2.敏感信息的展示

  牢記一點,第三方很有可能拿到你的平臺登錄權限(通過 session hijacking,或通過內部人),所以要未雨綢繆,敏感字段不要輕易示人!


  所以,敏感信息儘量不要明文展示,即使是合法用戶登錄狀態下。


  


  以下信息需“中間若干位星號顯示”,如果沒有特別理由,那麼默認不能直接顯示(包括導表):


(商戶的)銀行帳號,

(商戶的或用戶的)手機號碼和郵箱地址。

 


  鄭昀推薦你閱讀以下安全案例增進認識:


2013年,百度雲網盤用戶信息泄露:頁面上雖然星號顯示,但百度爬蟲抓取到了明文;

2013年,新網互聯找回密碼流程中,頁面上雖然顯示了星號遮擋的郵箱名,但HTML文檔中表單參數裏卻使用郵箱明文,導致土豆網域名被劫持。

 


1.9.平行權限像XSS一樣是每個新工程師都會跌入的大坑

  未判斷資源使用者與資源擁有者權限是否相符,新工程師特別容易犯這種錯誤,尤其是當框架或業務中心沒有做ACL限制的話。


  鄭昀推薦你閱讀這幾個典型安全案例,希望能警醒大家,犯這種錯誤真的覆水難收,能造成災難性後果:


2011年,知名案例,噹噹網收貨地址Ajax接口未校驗權限,導致用戶資料泄露;

2012年,知名案例,支付寶轉賬或交易結束後的結果頁面被 Google 收錄,搜索“site:cashier.alipay.com depositId”即可,導致交易信息泄漏;

與此類似的是,2013年,搜狗輸入法多媒體輸入功能的結果頁面被 Google 收錄,搜索“site:pinyin.cn”即可,導致用戶信息泄露;以及,2013年,百度手機輸入法增加貼心功能導致用戶信息泄露;

2013年,拉手網發送其他人拉手券(含密碼)到自己的手機上;

2013年,著名案例,利用新網的 domainManage 平行權限漏洞,註冊並登錄後,可修改任意域名DNS,導致大衆點評網域名被劫持。

  提醒兩點:


  第一,面向公衆用戶(C)的Web工程,URL上,或提交的表單裏,儘量不要出現整數類型的id(如訂單id,如商品id,如活動id,如地址id),否則容易被人猜出順序,隨意更改,從而遍歷數據。請加密你的整數類型id後傳遞(注:切勿直接MD5加密,因爲它等同於明文加密)。


  第二,面向C或商業用戶(B)的Web工程,接到資源的瀏覽或操作請求後,先校驗請求提交者的身份權限。


 


  公網上的權限校驗大體有幾種場景:


對於平臺運營商來說,肯定需要(高級)有權限對這些數據進行讀寫操作,如後臺管理平臺。

對於在平臺上開展業務的第三方來說,一旦與某一個用戶產生了直接的交易,那麼可能有權讀寫該用戶的數據,如讀取用戶部分信息,對用戶訂單發起退款申請。

登錄會員有權對自己的數據進行操作。

  針對這些場景,我們可能需要對目標數據的訪問進行不同邏輯的權限檢查。


  權限校驗規則:


如果是平臺運營系統請求數據,那麼信任發起者身份,不再進行權限校驗。

如果是平臺接入第三方請求數據,那麼應該檢查該數據的擁有者(即會員或系統管理員)是否授權該系統訪問其信息。

對於會員本身,需要檢查目標數據的擁有者與請求方是否同一用戶。

 


1.10.防表單重複提交

  有兩個含義:


頁面無刷新情況下,某些業務場景需要主動阻止表單重複提交:

有的業務場景支持重複提交但會提示:如實物類電商,同一個 SKU 提示重複加入購物車、但仍能加入購物車,只是在相同 SKU 上加數量;

有的場景會通過以下手法儘量提前避免表單(尤其是數據未變化的情況下)重複提交,而不用非要到服務器端在數據庫層面做重複數據判斷:

按鈕點擊後變灰(按鈕文字可以更改,如顯示倒計時),收到 Ajax 響應後再恢復,典型場景是填寫手機號碼點擊按鈕下發短信驗證碼時;

頁面刷新情況下,儘量阻止表單重複提交:

用戶行爲有:

用戶按F5刷新(注意,不是Ctrl+F5強制刷新);

用戶點擊瀏覽器的後退或前進功能回到之前的網頁;

這時需要服務器端配合了:

POST 表單提交後,服務器端做302跳轉,利用302跳轉清空表單參數;

延續 FormHash 思路,服務器端收到 formhash 值後存入緩存,幾分鐘後過期,這樣校驗邏輯可以阻止幾分鐘內的含相同 formhash 值的表單重複提交。

 


1.11.訪問速率限制Rate Limits

  有一些業務場景需要針對用戶短時間內過多的訪問頻次,制定不同的防範措施,如:


停止當前服務,提示訪問過於頻繁請稍後再試;

302跳轉到 ServerBusy 之類的頁面;

短時間內拒絕對方IP地址的請求,如三分鐘;

連續觸發報警閾值,則將對方IP加入黑名單,封殺較長時間,如一天。

  簡而言之,我們希望限制住的是,在用M度量的任何時間週期內,某一個動作(action)的發生次數N。


 


1.11.1.我們所希望的業務限流

  業務限流的目的是:


防掃號防暴力破解場景:防止對手高速掃描(或調用)我們的系統某個URI。這種場景經常發生在凌晨,對於異常訪問,我們系統必須第一時間攔截,在這種情況下,可能不允許太高的突發。

保證系統平穩運行:系統承載能力有限,數據庫支撐能力有限,所以不希望系統由於突發陡增請求而引發下游系統性能出現凸起,當然適量的波動是允許的。

  工程上有幾種做法:


1.11.2.簡單的memcache以秒爲單位的度量

 memcache 裏的 key 可以爲:業務編號_IP地址_時間戳_Limiter種類。時間戳精確到秒或分鐘。


 


1.11.3.漏桶(Leaky Bucket)算法

  Nginx 的 limitReq 模塊採用的就是漏桶算法,分 delay 和 nodelay 兩種處理模式。


  我們用實際例子來演示一下[注11]:


複製代碼

01     #以用戶二進制IP地址,定義三個漏桶,滴落速率1-3req/sec,桶空間1m,1M能保持大約16000個(IP)狀態

02     limit_req_zone  $binary_remote_addr  zone=qps1:1m   rate=1r/s;

03     limit_req_zone  $binary_remote_addr  zone=qps2:1m   rate=2r/s;

04     limit_req_zone  $binary_remote_addr  zone=qps3:1m   rate=3r/s;

05      

06     server {

07      

08     #速率qps=1,峯值burst=5,延遲請求

09     #嚴格按照漏桶速率qps=1處理每秒請求

10     #在峯值burst=5以內的併發請求,會被掛起,延遲處理

11     #超出請求數限制則直接返回503

12     #客戶端只要控制併發在峯值[burst]內,就不會觸發limit_req_error_log

13     # 例1:發起一個併發請求=6,拒絕1個,處理1個,進入延遲隊列4個:

14     #time    request    refuse    sucess    delay

15     #00:01        6        1        1            4

16     #00:02        0        0        1            3

17     #00:03        0        0        1            2

18     #00:04        0        0        1            1

19     #00:05        0        0        1            0

20     location /delay {

21         limit_req   zone=qps1  burst=5;

22     }

23      

24     #速率qps=1,峯值burst=5,不延遲請求

25     #加了nodelay之後,漏桶控制一段時長內的平均qps = 漏桶速率,允許瞬時的峯值qps > 漏桶qps

26     #所以峯值時的最高qps=(brust+qps-1)=5

27     #請求不會被delay,要麼處理,要麼直接返回503

28     #客戶端需要控制qps每秒請求數,纔不會觸發limit_req_error_log

29     # 例2:每隔5秒發起一次達到峯值的併發請求,由於時間段內平均qps=1 所以仍然符合漏桶速率:

30     #time    request     refuse    sucess

31     #00:01         5         0          5

32     #00:05         5         0          5

33     #00:10         5         0          5

34     # 例3:連續每秒發起併發請求=5,由於時間段內平均qps>>1,超出的請求被拒絕:

35     #time    request     refuse     sucess

36     #00:01         5         0           5

37     #00:02         5         4           1

38     #00:03         5         4           1

39      

40     location /nodelay {

41         limit_req   zone=qps1  burst=5 nodelay;

42     }

43      

44     }

複製代碼

 


1.11.4.令牌桶(Token Bucket)算法

  令牌桶具體實現:


  在數據結構上,沒有必要真的實現一個令牌桶。


  基於時間的流逝生成受控制數量的令牌即可——以時間的流逝來洗滌舊跡,也就是將兩次發包或者收包的間隔和令牌數量聯繫起來。


 


  令牌桶和漏桶算法最主要的差別在於:漏桶算法能夠強行限制數據的傳輸速率,而令牌桶算法能夠在限制數據的平均傳輸速率的同時還允許某種程度的突發傳輸。


 


  相對於漏桶算法,令牌桶的波動幅度可能是我們系統無法承受的。


  令牌是基於 Request 觸發投放到令牌桶的,如果是按照下面的投放策略:


            delta = self.fill_rate * (now - self.timestamp)#fill_rate is the rate in tokens/second that the bucket will be refilled.


            self._tokens = min(self.capacity, self._tokens + delta)


  那麼代入演算一下,令牌桶令牌總數 capacity=80,還剩餘0張令牌,令牌桶填充速率fill_rate=0.5t/s,流逝的時間是10秒,即過去的10秒沒有任何請求,第11秒突然拿來了一個請求,於是令牌桶裏就會放入min(80,5)=5張令牌,意味着第11秒可以消耗5個令牌。


  這也就是我們爲什麼說令牌桶算法是“只要令牌桶中存在令牌,那麼就允許突發地傳輸數據直到達到用戶配置的上限,因此它適合於具有突發特性的流量”的緣故。


 


  瞭解更多漏桶和令牌桶算法信息,請參考鄭昀的《集羣環境下業務限流[注10]》。


 


1.11.5.滑窗(Sliding Window)算法

  淘寶中間件博客上曾提及,『流量預警和限流方案中,滑窗模式通過統計多個單元時間的訪問次數來進行控制,當單位時間的訪問次數達到某個峯值時進行限流。


  在每次有訪問進來時,我們判斷前N個單位時間裏總訪問量是否超過了設置的閾值,若超過則不允許執行。


缺點一:


由於訪問量的不可預見性,會出現單位時間的前半段有大量請求涌入,而後半段則拒絕所有請求的情況發生。


缺點二:


其次,我們很難確定這個閾值設置在多少比較合適,只能通過經驗或者模擬(如壓測)來估算。不過即使是壓測也很難估計準確。


  所以滑窗模式往往用來對某一資源的保護上(或者說是承諾比較合適:我對某一接口的提供者承諾過,最高調用量不超過XX),如對 DB 的保護,對某一服務的調用的控制上。


 


  代碼實現思路如下:


  每一個窗(單位時間)就是一個獨立的計數器(原子計數器),用以數組保存。將當前時間以某種方式(比如取模)映射到數組的一項中。每次訪問先對當前窗內計數器+1,再計算前N個單元格的訪問量綜合,超過閾值則限流。


  這裏有個問題,時間永遠是遞增的,單純的取模,會導致數組過長,使用內存過多,我們可以用環形隊列來解決這個問題。』



轉自網絡:http://www.cnblogs.com/zhengyun_ustc/p/rule1.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章