關(guān)于服務(wù)限流這回事,總算整明白了
?前言
隨著現(xiàn)在微服務(wù)、分布式系統(tǒng)的發(fā)展,各個(gè)服務(wù)之間的相互調(diào)用越來越復(fù)雜。為了保證自身服務(wù)的穩(wěn)定性與高可用,當(dāng)面對超過自身服務(wù)能力的請求調(diào)用時(shí),要做一定的限流措施。如同五一、國慶期間的旅游出行、景區(qū)爆滿,游客限流。我們的服務(wù)面對諸如秒殺、大促、618、雙十一以及可能的惡意攻擊、爬蟲等高并發(fā)、大流量的場景也需要做服務(wù)限流。
對超出服務(wù)處理能力之外的請求進(jìn)行攔截,對訪問服務(wù)的流量進(jìn)行限制,這就是服務(wù)限流。接下來我們就好好談?wù)劮?wù)限流這回事兒。
兩種限流方式
常見的限流方式可以分為兩類:基于請求限流和基于資源限流。
- 基于請求限流
基于請求限流指從外部訪問的請求角度考慮限流,常見的方式有兩種。
第一種是限制總量,也就是限制某個(gè)指標(biāo)的累積上限,常見的是限制當(dāng)前系統(tǒng)服務(wù)的用戶總量,例如:某個(gè)直播間限制總用戶數(shù)上限為100萬,超過100萬后新的用戶無法進(jìn)入;某個(gè)搶購活動(dòng)商品數(shù)量只有100個(gè),限制參與搶購的用戶上限為1萬個(gè),1萬以后的用戶直接拒絕。
第二種是限制時(shí)間量,也就是限制一段時(shí)間內(nèi)某個(gè)指標(biāo)的上限,例如1分鐘內(nèi)只允許10000個(gè)用戶訪問;每秒請求峰值最高為10萬。
優(yōu)點(diǎn):
- 實(shí)現(xiàn)簡單
缺點(diǎn):
- 實(shí)踐中面臨的主要問題是比較難以找到合適的閾值。例如系統(tǒng)設(shè)定了1分鐘10000個(gè)用戶,但實(shí)際上6000個(gè)用戶的時(shí)候系統(tǒng)就扛不住了;或者達(dá)到1分鐘10000用戶后,其實(shí)系統(tǒng)壓力還不大,但此時(shí)已經(jīng)開始丟棄用戶訪問了。而且還要考慮硬件相關(guān)的因素,例如一臺32核的機(jī)器和64核的機(jī)器處理能力差別很大,閾值是不同的。
應(yīng)用:
- 適用于業(yè)務(wù)功能比較簡單的系統(tǒng),例如負(fù)載均衡系統(tǒng)、網(wǎng)關(guān)系統(tǒng)、搶購系統(tǒng)等。
- 基于資源限流
基于請求限流是從系統(tǒng)外部考慮的,而基于資源限流是從系統(tǒng)內(nèi)部考慮的,也就是找到系統(tǒng)內(nèi)部影響性能的關(guān)鍵資源,對其使用上限進(jìn)行限制。常見的內(nèi)部資源包括連接數(shù)、文件句柄、線程數(shù)和請求隊(duì)列等。比如CPU的占用率超過80%的時(shí)候就開始拒絕新的請求。
優(yōu)點(diǎn):
- 有效地反映當(dāng)前系統(tǒng)的壓力,更好的進(jìn)行限流
缺點(diǎn):
- 難以確定關(guān)鍵資源
- 難以確定關(guān)鍵資源的閾值,需要在線上逐步調(diào)試,持續(xù)觀察,直到找到合適的值。
應(yīng)用:
- 適用于具體的某個(gè)服務(wù),比如訂單系統(tǒng)、商品系統(tǒng)等。
四種限流算法
常見的限流算法有4種,它們的實(shí)現(xiàn)原理和優(yōu)缺點(diǎn)各不相同,在實(shí)際設(shè)計(jì)的時(shí)候需要根據(jù)業(yè)務(wù)場景來選擇。
- 固定時(shí)間窗
固定時(shí)間窗算法的實(shí)現(xiàn)原理是,統(tǒng)計(jì)固定時(shí)間周期內(nèi)的請求量或者資源消耗量,超過限額就會(huì)啟動(dòng)限流,如下圖所示:
優(yōu)點(diǎn):
- 實(shí)現(xiàn)簡單
缺點(diǎn):
- 存在臨界點(diǎn)問題。例如上圖中的紅藍(lán)兩點(diǎn)只間隔了短短10秒,期間的請求數(shù)卻已經(jīng)達(dá)到200,超過了算法規(guī)定的限額(1分鐘內(nèi)處理100)。但是因?yàn)檫@些請求分別來自兩個(gè)統(tǒng)計(jì)窗口,從單個(gè)窗口來看還沒有超出限額,所以并不會(huì)啟動(dòng)限流,結(jié)果可能導(dǎo)致系統(tǒng)因?yàn)閴毫^大而掛掉。
- 滑動(dòng)時(shí)間窗
為了解決臨界點(diǎn)問題,滑動(dòng)時(shí)間窗算法應(yīng)運(yùn)而生,它的實(shí)現(xiàn)原理是,兩個(gè)統(tǒng)計(jì)周期部分重疊,從而避免短時(shí)間內(nèi)的兩個(gè)統(tǒng)計(jì)點(diǎn)分屬不同的時(shí)間窗的情況,如下圖所示:
優(yōu)點(diǎn):
- 不存在臨界點(diǎn)問題
缺點(diǎn):
- 相對于固定窗口,復(fù)雜度有所提升
- 漏桶算法
漏桶算法的實(shí)現(xiàn)原理是,將請求放入“桶”(消息隊(duì)列等),業(yè)務(wù)處理單元(線程、進(jìn)程和應(yīng)用等)從桶里拿請求處理,桶滿則丟棄新的請求,如下圖所示:
優(yōu)點(diǎn):
- 突發(fā)大量流量時(shí)丟棄的請求較少,因?yàn)槁┩氨旧碛芯彺嬲埱蟮淖饔?/li>
缺點(diǎn):
- 可以平滑流量,但是無法解決流量突增的問題。
- 桶大小動(dòng)態(tài)調(diào)整比較困難,需要不斷的嘗試才能找到符合業(yè)務(wù)需求的最佳桶大小。
- 無法精確控制流出速度,也就是業(yè)務(wù)的處理速度。
漏桶算法主要適用于瞬時(shí)高并發(fā)流量的場景(例如剛才提到的0點(diǎn)簽到、整點(diǎn)秒殺等)。在短短幾分鐘內(nèi)涌入大量請求時(shí),為了更好的業(yè)務(wù)效果和用戶體驗(yàn),即使處理慢一些,也要做到盡量不丟棄用戶請求。
- 令牌桶算法
令牌桶算法和漏桶算法的不同之處在于,桶中放入的不是請求,而是“令牌”,這個(gè)令牌就是業(yè)務(wù)處理前需要拿到的“許可證”。也就是說,當(dāng)系統(tǒng)收到一個(gè)請求時(shí),先要到令牌桶里面拿“令牌”,拿到令牌才能進(jìn)一步處理,拿不到就要丟棄請求。
它的實(shí)現(xiàn)原理是如下圖所示:
優(yōu)點(diǎn):
- 通過控制放入令牌的速率,可以動(dòng)態(tài)調(diào)整處理速率,實(shí)現(xiàn)更加靈活。
- 可以平滑限流,同時(shí)可以容忍突發(fā)流量,因?yàn)橥袄锩婵梢岳鄯e一定數(shù)量的令牌,當(dāng)突發(fā)流量過來的時(shí)候,桶里面有累積的令牌,此時(shí)的業(yè)務(wù)處理速度會(huì)超過令牌放入的速度。
缺點(diǎn):
- 突發(fā)大量流量的時(shí)候可能丟棄很多請求,因?yàn)榱钆仆安荒芾鄯e太多令牌。
- 實(shí)現(xiàn)相對復(fù)雜。
令牌桶算法主要適用于兩種典型的場景,一種是需要控制訪問第三方服務(wù)的速度,防止把下游壓垮,例如支付寶需要控制訪問銀行接口的速率;另一種是需要控制自己的處理速度,防止過載,例如壓測結(jié)果顯示系統(tǒng)最大處理TPS是100,那么就可以用令牌桶來限制最大的處理速度。
五種限流策略
- 服務(wù)拒絕
當(dāng)請求流量達(dá)到限流閾值時(shí),對多余的請求直接拒絕。
可通過設(shè)計(jì)實(shí)現(xiàn)對指定域名、IP、客戶端、應(yīng)用、用戶等不同來源的請求進(jìn)行拒絕。
- 延時(shí)處理
通過將多余的請求加入緩存隊(duì)列或延時(shí)隊(duì)列,來應(yīng)對短期的流量突增,高峰期過后開始將堆積的請求流量逐漸處理。
- 請求分級(優(yōu)先級)
對不同來源的請求設(shè)置優(yōu)先級,先處理優(yōu)先級更高的請求。如VIP客戶、重要的業(yè)務(wù)應(yīng)用(如交易服務(wù)優(yōu)先級高于日志服務(wù))。
- 動(dòng)態(tài)限流
可以監(jiān)控系統(tǒng)相關(guān)指標(biāo)、評估系統(tǒng)壓力,通過注冊中心、配置中心等動(dòng)態(tài)調(diào)整限流閾值。
- 監(jiān)控預(yù)警&動(dòng)態(tài)擴(kuò)容
如果有優(yōu)秀的服務(wù)監(jiān)控系統(tǒng)與自動(dòng)部署、發(fā)布系統(tǒng),可以通過監(jiān)控系統(tǒng)自動(dòng)監(jiān)測系統(tǒng)運(yùn)行情況,對短期內(nèi)服務(wù)壓力暴增、流量大幅寫入的情況進(jìn)行郵件、短信等方式進(jìn)行預(yù)警。
在滿足特定條件下,可自動(dòng)部署、發(fā)布相關(guān)服務(wù),起到動(dòng)態(tài)擴(kuò)容的效果。
三個(gè)限流位置
- 接入層限流
可以通過Nginx、API路由網(wǎng)關(guān)等對域名或IP進(jìn)行限流,同時(shí)可以攔截非法請求。
- 應(yīng)用限流
每個(gè)服務(wù)可以有自己的單機(jī)或集群限流措施,也可以調(diào)用第三方的限流服務(wù),比如阿里的Sentinel限流框架。
- 基礎(chǔ)服務(wù)限流
也可以對基礎(chǔ)服務(wù)層進(jìn)行限流。
- 數(shù)據(jù)庫:限制數(shù)據(jù)庫連接、限制讀寫速率
- 消息隊(duì)列:限制消費(fèi)速率(消費(fèi)量、消費(fèi)線程)
總結(jié)
本文從宏觀角度總結(jié)了服務(wù)限流的兩種方式,三個(gè)可以限流的位置,四種常見的限流算法,五種限流的策略。最后再補(bǔ)充幾句,合理的限流配置,需要了解系統(tǒng)的吞吐量,所以,限流一般需要結(jié)合容量規(guī)劃和壓測來進(jìn)行。當(dāng)外部請求接近或者達(dá)到系統(tǒng)的最大閾值時(shí),觸發(fā)限流,采取其他的手段進(jìn)行降級,保護(hù)系統(tǒng)不被壓垮。
參考:http://www.studyofnet.com/555653372.html