在早期的計算機(jī)領(lǐng)域,限流技術(shù)(time limiting)被用作控制網(wǎng)絡(luò)接口收發(fā)通信數(shù)據(jù)的速率。 可以用來優(yōu)化性能,減少延遲和提高帶寬等。 現(xiàn)在在互聯(lián)網(wǎng)領(lǐng)域,也借鑒了這個概念, 用來為服務(wù)控制請求的速率, 如果雙十一的限流, 12306的搶票等。 即使在細(xì)粒度的軟件架構(gòu)中,也有類似的概念。 兩種常用算法 令牌桶(Token Bucket)和漏桶(leaky bucket)是 最常用的兩種限流的算法。 漏桶算法 它的主要目的是控制數(shù)據(jù)注入到網(wǎng)絡(luò)的速率,平滑網(wǎng)絡(luò)上的突發(fā)流量。漏桶算法提供了一種機(jī)制,通過它,突發(fā)流量可以被整形以便為網(wǎng)絡(luò)提供一個穩(wěn)定的流量。 漏桶可以看作是一個帶有常量服務(wù)時間的單服務(wù)器隊列,如果漏桶(包緩存)溢出,那么數(shù)據(jù)包會被丟棄。 用說人話的講: 漏桶算法思路很簡單,水(數(shù)據(jù)或者請求)先進(jìn)入到漏桶里,漏桶以一定的速度出水,當(dāng)水流入速度過大會直接溢出,可以看出漏桶算法能強(qiáng)行限制數(shù)據(jù)的傳輸速率。 在某些情況下,漏桶算法不能夠有效地使用網(wǎng)絡(luò)資源。因?yàn)槁┩暗穆┏鏊俾适枪潭ǖ膮?shù),所以,即使網(wǎng)絡(luò)中不存在資源沖突(沒有發(fā)生擁塞),漏桶算法也不能使某一個單獨(dú)的流突發(fā)到端口速率。因此,漏桶算法對于存在突發(fā)特性的流量來說缺乏效率。而令牌桶算法則能夠滿足這些具有突發(fā)特性的流量。通常,漏桶算法與令牌桶算法可以結(jié)合起來為網(wǎng)絡(luò)流量提供更大的控制。 令牌桶算法 令牌桶算法的原理是系統(tǒng)會以一個恒定的速度往桶里放入令牌,而如果請求需要被處理,則需要先從桶里獲取一個令牌,當(dāng)桶里沒有令牌可取時,則拒絕服務(wù)。 令牌桶的另外一個好處是可以方便的改變速度。 一旦需要提高速率,則按需提高放入桶中的令牌的速率。 一般會定時(比如100毫秒)往桶中增加一定數(shù)量的令牌, 有些變種算法則實(shí)時的計算應(yīng)該增加的令牌的數(shù)量, 比如華為的專利"采用令牌漏桶進(jìn)行報文限流的方法"(CN 1536815 A),提供了一種動態(tài)計算可用令牌數(shù)的方法, 相比其它定時增加令牌的方法, 它只在收到一個報文后,計算該報文與前一報文到來的時間間隔內(nèi)向令牌漏桶內(nèi)注入的令牌數(shù), 并計算判斷桶內(nèi)的令牌數(shù)是否滿足傳送該報文的要求。 從最終用戶訪問安全的角度看,設(shè)想有人想暴力碰撞網(wǎng)站的用戶密碼;或者有人攻擊某個很耗費(fèi)資源的接口;或者有人想從某個接口大量抓取數(shù)據(jù)。大部分人都知道應(yīng)該增加 Rate limiting,做請求頻率限制。從安全角度,這個可能也是大部分能想到,但不一定去做的薄弱環(huán)節(jié)。 從整個架構(gòu)的穩(wěn)定性角度看,一般 SOA 架構(gòu)的每個接口的有限資源的情況下,所能提供的單位時間服務(wù)能力是有限的。假如超過服務(wù)能力,一般會造成整個接口服務(wù)停頓,或者應(yīng)用 Crash,或者帶來連鎖反應(yīng),將延遲傳遞給服務(wù)調(diào)用方造成整個系統(tǒng)的服務(wù)能力喪失。有必要在服務(wù)能力超限的情況下 Fail Fast。 另外,根據(jù)排隊論,由于 API 接口服務(wù)具有延遲隨著請求量提升迅速提升的特點(diǎn),為了保證 SLA 的低延遲,需要控制單位時間的請求量。這也是 Little’s law 所說的。
還有,公開 API 接口服務(wù),Rate limiting 應(yīng)該是一個必備的功能,否則公開的接口不知道哪一天就會被服務(wù)調(diào)用方有意無意的打垮。 所以,提供資源能夠支撐的服務(wù),將過載請求快速拋棄對整個系統(tǒng)架構(gòu)的穩(wěn)定性非常重要。這就要求在應(yīng)用層實(shí)現(xiàn) Rate limiting 限制。 常見的 Rate limiting 的實(shí)現(xiàn)方式Proxy 層的實(shí)現(xiàn),針對部分 URL 或者 API 接口進(jìn)行訪問頻率限制Nginx 模塊limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s; server { location /search/ { limit_req zone=one burst=5; }
詳細(xì)參見: ngx_http_limit_req_module Haproxy 提供的功能詳細(xì)參見: Haproxy Rate limit 模塊
RateLimiters是令牌桶和漏桶在.NET 中實(shí)現(xiàn)。這些策略可用于速率限制請求不同的網(wǎng)站中,后端或 API 調(diào)用等場景。
ASP.NET Web API rate limiter for IIS and Owin hosting 基于 Redis 功能的實(shí)現(xiàn)這個在 Redis 官方文檔有非常詳細(xì)的實(shí)現(xiàn)。一般適用于所有類型的應(yīng)用,比如 PHP、Python 等等。Redis 的實(shí)現(xiàn)方式可以支持分布式服務(wù)的訪問頻率的集中控制。Redis 的頻率限制實(shí)現(xiàn)方式還適用于在應(yīng)用中無法狀態(tài)保存狀態(tài)的場景。
網(wǎng)上有眾多關(guān)于這方面的文章,這里列出了本文參考的一些文檔。
|
|