流量調整和接口限流技術的總結

wsja0071 8年前發布 | 16K 次閱讀 Redis 軟件架構

一、問題描述

某天A君突然發現自己的接口請求量突然漲到之前的10倍,沒多久該接口幾乎不可使用,并引發連鎖反應導致整個系統崩潰。如何應對這種情況呢?生活給了我們答案:比如老式電閘都安裝了保險絲,一旦有人使用超大功率的設備,保險絲就會燒斷以保護各個電器不被強電流給燒壞。同理我們的接口也需要安裝上“保險絲”,以防止非預期的請求對系統壓力過大而引起的系統癱瘓,當流量過大時,可以采取拒絕或者引流等機制。

二、常用的限流算法

常用的限流算法有兩種: 漏桶 算法和 令牌桶 算法。

它的主要目的是控制數據注入到網絡的速率,平滑網絡上的突發流量。漏桶算法提供了一種機制,通過它,突發流量可以被整形以便為網絡提供一個穩定的流量。 漏桶可以看作是一個帶有常量服務時間的單服務器隊列,如果漏桶(包緩存)溢出,那么數據包會被丟棄。 用說人話的講:

漏桶算法思路很簡單,水(數據或者請求)先進入到漏桶里,漏桶以一定的速度出水,當水流入速度過大會直接溢出,可以看出漏桶算法能強行限制數據的傳輸速率。

圖1 漏桶算法示意圖

對于很多應用場景來說,除了要求能夠限制數據的平均傳輸速率外,還要求允許某種程度的突發傳輸。這時候漏桶算法可能就不合適了,令牌桶算法更為適合。如圖2所示,令牌桶算法的原理是系統會以一個恒定的速度往桶里放入令牌,而如果請求需要被處理,則需要先從桶里獲取一個令牌,當桶里沒有令牌可取時,則拒絕服務。

圖2 令牌桶算法示意圖

令牌桶算法的原理是系統會以一個恒定的速度往桶里放入令牌,而如果請求需要被處理,則需要先從桶里獲取一個令牌,當桶里沒有令牌可取時,則拒絕服務。 令牌桶的另外一個好處是可以方便的改變速度。 一旦需要提高速率,則按需提高放入桶中的令牌的速率。 一般會定時(比如100毫秒)往桶中增加一定數量的令牌, 有些變種算法則實時的計算應該增加的令牌的數量, 比如華為的專利"采用令牌漏桶進行報文限流的方法"(CN 1536815 A),提供了一種動態計算可用令牌數的方法, 相比其它定時增加令牌的方法, 它只在收到一個報文后,計算該報文與前一報文到來的時間間隔內向令牌漏桶內注入的令牌數, 并計算判斷桶內的令牌數是否滿足傳送該報文的要求。

從最終用戶訪問安全的角度看,設想有人想暴力碰撞網站的用戶密碼;或者有人攻擊某個很耗費資源的接口;或者有人想從某個接口大量抓取數據。大部分人都知道應該增加 Rate limiting,做請求頻率限制。從安全角度,這個可能也是大部分能想到,但不一定去做的薄弱環節。

從整個架構的穩定性角度看,一般 SOA 架構的每個接口的有限資源的情況下,所能提供的單位時間服務能力是有限的。假如超過服務能力,一般會造成整個接口服務停頓,或者應用 Crash,或者帶來連鎖反應,將延遲傳遞給服務調用方造成整個系統的服務能力喪失。有必要在服務能力超限的情況下 Fail Fast。

另外,根據排隊論,由于 API 接口服務具有延遲隨著請求量提升迅速提升的特點,為了保證 SLA 的低延遲,需要控制單位時間的請求量。這也是 Little’s law 所說的。

還有,公開 API 接口服務,Rate limiting 應該是一個必備的功能,否則公開的接口不知道哪一天就會被服務調用方有意無意的打垮。

所以,提供資源能夠支撐的服務,將過載請求快速拋棄對整個系統架構的穩定性非常重要。這就要求在應用層實現 Rate limiting 限制。

常見的 Rate limiting 的實現方式

Proxy 層的實現,針對部分 URL 或者 API 接口進行訪問頻率限制

Nginx 模塊:

limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

server { location /search/ { limit_req zone=one burst=5; }</pre>

基于 Redis 功能的實現:

這個在 Redis 官方文檔有非常詳細的實現。一般適用于所有類型的應用,比如 PHP、Python 等等。Redis 的實現方式可以支持分布式服務的訪問頻率的集中控制。Redis 的頻率限制實現方式還適用于在應用中無法狀態保存狀態的場景。

參考: Rate limiter

本文內容參考:

1、 http://www.cnblogs.com/zhengyun_ustc/archive/2012/11/17/topic1.html

2、 http://www.cnblogs.com/shanyou/p/4280546.html

 

來自:http://blog.41ms.com/post/61.html

 

 本文由用戶 wsja0071 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!