溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

大數(shù)據(jù)中流控降級(jí)的示例分析

發(fā)布時(shí)間:2021-11-17 10:40:08 來(lái)源:億速云 閱讀:148 作者:小新 欄目:大數(shù)據(jù)

這篇文章主要為大家展示了“大數(shù)據(jù)中流控降級(jí)的示例分析”,內(nèi)容簡(jiǎn)而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“大數(shù)據(jù)中流控降級(jí)的示例分析”這篇文章吧。

流控降級(jí)最佳實(shí)踐

  • 生產(chǎn)環(huán)境經(jīng)常會(huì)出現(xiàn)以下不穩(wěn)定的情況:

  • 大促時(shí)瞬間洪峰流量導(dǎo)致系統(tǒng)超出最大負(fù)載,load 飆高,系統(tǒng)崩潰導(dǎo)致用戶(hù)無(wú)法下單

  • “黑馬”熱點(diǎn)商品擊穿緩存,DB 被打垮,擠占正常流量

  • 調(diào)用端被不穩(wěn)定服務(wù)拖垮,線(xiàn)程池被占滿(mǎn),導(dǎo)致整個(gè)調(diào)用鏈路卡死

這些不穩(wěn)定的場(chǎng)景可能會(huì)導(dǎo)致嚴(yán)重后果。大家可能想問(wèn):如何做到均勻平滑的用戶(hù)訪(fǎng)問(wèn)?如何預(yù)防這些不穩(wěn)定因素帶來(lái)的影響?這時(shí)候我們就要請(qǐng)出微服務(wù)穩(wěn)定性的法寶 —— 流控降級(jí)。流量控制和熔斷降級(jí)是保障微服務(wù)穩(wěn)定性重要的一環(huán)。本文將會(huì)幫助讀者理解流控降級(jí)的重要性,并介紹流控降級(jí)的各種最佳實(shí)踐場(chǎng)景。如有遺漏或錯(cuò)誤,歡迎補(bǔ)充指正。

什么是流控降級(jí)

流控,即流量控制。流量控制在網(wǎng)絡(luò)傳輸中是一個(gè)常用的概念,它用于調(diào)整網(wǎng)絡(luò)包的發(fā)送數(shù)據(jù)。然而,從系統(tǒng)穩(wěn)定性角度考慮,在處理請(qǐng)求的速度上,也有非常多的講究。任意時(shí)間到來(lái)的請(qǐng)求往往是隨機(jī)不可控的,而系統(tǒng)的處理能力是有限的。我們需要根據(jù)系統(tǒng)的處理能力對(duì)流量進(jìn)行控制,在保證系統(tǒng)吞吐量比較高的同時(shí)又不會(huì)把系統(tǒng)打垮。

熔斷降級(jí)則是在服務(wù)出現(xiàn)不穩(wěn)定因素的時(shí)候暫時(shí)切斷服務(wù)的調(diào)用,等待一段時(shí)間再進(jìn)行嘗試。一方面防止給不穩(wěn)定服務(wù)“雪上加霜”,另一方面保護(hù)服務(wù)的調(diào)用方不被拖垮。這其實(shí)就是熔斷器(Circuit Breaker)的思想:

<img src="https://user-images.githubusercontent.com/9434884/62473394-3bc10a00-b7d3-11e9-8998-68d9cf3e01f2.png" alt="circuit-breaker" width="50%"/>

為什么需要流控降級(jí)

流量是非常隨機(jī)性的、不可預(yù)測(cè)的。前一秒可能還風(fēng)平浪靜,后一秒可能就出現(xiàn)流量洪峰了(例如雙十一零點(diǎn)的場(chǎng)景)。然而我們系統(tǒng)的容量總是有限的,如果突然而來(lái)的流量超過(guò)了系統(tǒng)的承受能力,就可能會(huì)導(dǎo)致請(qǐng)求處理不過(guò)來(lái),堆積的請(qǐng)求處理緩慢,CPU/Load 飆高,最后導(dǎo)致系統(tǒng)崩潰。因此,我們需要針對(duì)這種突發(fā)的流量來(lái)進(jìn)行限制,在盡可能處理請(qǐng)求的同時(shí)來(lái)保障服務(wù)不被打垮。

一個(gè)服務(wù)常常會(huì)調(diào)用別的模塊,可能是另外的一個(gè)遠(yuǎn)程服務(wù)、數(shù)據(jù)庫(kù),或者第三方 API 等。例如,支付的時(shí)候,可能需要遠(yuǎn)程調(diào)用銀聯(lián)提供的 API;查詢(xún)某個(gè)商品的價(jià)格,可能需要進(jìn)行數(shù)據(jù)庫(kù)查詢(xún)。然而,這個(gè)被依賴(lài)服務(wù)的穩(wěn)定性是不能保證的。如果依賴(lài)的服務(wù)出現(xiàn)了不穩(wěn)定的情況,請(qǐng)求的響應(yīng)時(shí)間變長(zhǎng),那么調(diào)用服務(wù)的方法的響應(yīng)時(shí)間也會(huì)變長(zhǎng),線(xiàn)程會(huì)產(chǎn)生堆積,最終可能耗盡業(yè)務(wù)自身的線(xiàn)程池,服務(wù)本身也變得不可用。

大數(shù)據(jù)中流控降級(jí)的示例分析

現(xiàn)代微服務(wù)架構(gòu)都是分布式的,由非常多的服務(wù)組成。不同服務(wù)之間相互調(diào)用,組成復(fù)雜的調(diào)用鏈路。以上的問(wèn)題在鏈路調(diào)用中會(huì)產(chǎn)生放大的效果。復(fù)雜鏈路上的某一環(huán)不穩(wěn)定,就可能會(huì)層層級(jí)聯(lián),最終導(dǎo)致整個(gè)鏈路都不可用。因此我們需要對(duì)不穩(wěn)定的服務(wù)進(jìn)行熔斷降級(jí),暫時(shí)切斷不穩(wěn)定調(diào)用,避免局部不穩(wěn)定因素導(dǎo)致整體的雪崩。

那么是不是服務(wù)的量級(jí)很小就不用進(jìn)行限流防護(hù)了呢?是不是微服務(wù)的架構(gòu)比較簡(jiǎn)單就不用引入熔斷保護(hù)機(jī)制了呢?其實(shí),這與請(qǐng)求的量級(jí)、架構(gòu)的復(fù)雜程度無(wú)關(guān)。很多時(shí)候,可能正是一個(gè)非常邊緣的服務(wù)出現(xiàn)故障而導(dǎo)致整體業(yè)務(wù)受影響,造成巨大損失。我們需要具有面向失敗設(shè)計(jì)的意識(shí),在平時(shí)就做好容量規(guī)劃和強(qiáng)弱依賴(lài)的梳理,合理地配置流控降級(jí)規(guī)則,做好事前防護(hù),而不是在線(xiàn)上出現(xiàn)問(wèn)題以后再進(jìn)行補(bǔ)救。

流控降級(jí)最佳實(shí)踐

下面我們會(huì)介紹幾個(gè)常見(jiàn)場(chǎng)景下的流控降級(jí)最佳實(shí)踐,幫助大家合理地利用流控降級(jí)來(lái)保障服務(wù)的穩(wěn)定性。

服務(wù)提供方流控

在服務(wù)提供方(Service Provider)的場(chǎng)景下,我們需要保護(hù)服務(wù)提供方自身不被流量洪峰打垮。我們通常根據(jù)服務(wù)提供方的服務(wù)能力進(jìn)行流量控制,或針對(duì)特定的服務(wù)調(diào)用方進(jìn)行限制。

為了保護(hù)服務(wù)提供方不被激增的流量拖垮影響穩(wěn)定性,我們可以配置 QPS 模式的限流,當(dāng)每秒的請(qǐng)求量超過(guò)設(shè)定的閾值時(shí),會(huì)自動(dòng)拒絕多余的請(qǐng)求。

根據(jù)調(diào)用方的需求來(lái)分配服務(wù)提供方的處理能力也是常見(jiàn)的限流方式。例如,有兩個(gè)服務(wù)消費(fèi)者 A 和 B 都向服務(wù)提供方發(fā)起調(diào)用請(qǐng)求,我們希望優(yōu)先處理消費(fèi)者 A 的請(qǐng)求,而只對(duì)來(lái)自服務(wù) B 的請(qǐng)求進(jìn)行限流。

服務(wù)調(diào)用方隔離/熔斷

除了根據(jù)服務(wù)能力進(jìn)行流量控制以外,還有一種常見(jiàn)的場(chǎng)景,即對(duì)依賴(lài)方進(jìn)行隔離和降級(jí)。前面提到過(guò),分布式系統(tǒng)中難免會(huì)有不穩(wěn)定的服務(wù)節(jié)點(diǎn)(請(qǐng)求慢或請(qǐng)求處理失敗)。如果調(diào)用端不引入自我保護(hù)的機(jī)制,那么有可能會(huì)被依賴(lài)的不穩(wěn)定服務(wù)拖垮,導(dǎo)致自身也不可用。分布式系統(tǒng)中服務(wù)間的依賴(lài)關(guān)系是非常復(fù)雜的,一個(gè)服務(wù)不可用可能會(huì)導(dǎo)致上游數(shù)個(gè)服務(wù)不可用,最終會(huì)導(dǎo)致雪崩。

對(duì)這種情況,我們要在服務(wù)調(diào)用端(Service Consumer)對(duì)依賴(lài)的不穩(wěn)定服務(wù)進(jìn)行隔離和熔斷。

服務(wù)隔離一般有兩種方式:

  • 線(xiàn)程池隔離:即針對(duì)不同的業(yè)務(wù)調(diào)用分別創(chuàng)建不同的線(xiàn)程池,不同服務(wù)調(diào)用都發(fā)生在不同的線(xiàn)程池中,在線(xiàn)程池排隊(duì)、超時(shí)等阻塞情況時(shí)可以快速“掐斷”。線(xiàn)程池隔離的好處是隔離度比較高,可以針對(duì)某個(gè)服務(wù)調(diào)用的線(xiàn)程池去進(jìn)行處理而不影響其它資源,但是代價(jià)就是可能會(huì)創(chuàng)建比較多的線(xiàn)程池,線(xiàn)程上下文切換的 overhead 比較大,而且線(xiàn)程池執(zhí)行會(huì)導(dǎo)致一些基于 ThreadLocal 的場(chǎng)景出現(xiàn)問(wèn)題(如 Spring 事務(wù))。Hystrix 主推線(xiàn)程池隔離模式。

  • 信號(hào)量隔離:即限制某個(gè)服務(wù)調(diào)用的并發(fā)量,而不是為不同服務(wù)顯式創(chuàng)建線(xiàn)程池。這樣的隔離比較輕量,overhead 比較小,但是效果不錯(cuò),并且可以結(jié)合實(shí)時(shí)的響應(yīng)時(shí)間對(duì)慢調(diào)用進(jìn)行熔斷,從而保障自身不被不穩(wěn)定服務(wù)調(diào)用所拖垮。Sentinel 主推信號(hào)量隔離模式。

當(dāng)服務(wù)依賴(lài)于多個(gè)下游服務(wù),而某個(gè)下游服務(wù)調(diào)用非常慢或經(jīng)常出錯(cuò)時(shí),會(huì)嚴(yán)重影響當(dāng)前服務(wù)的調(diào)用。我們可以借助熔斷器的思想,當(dāng)異常比率或業(yè)務(wù)調(diào)用的平均時(shí)長(zhǎng)超過(guò)某個(gè)閾值后將調(diào)用進(jìn)行熔斷,直到一段時(shí)間過(guò)后再?lài)L試恢復(fù)。熔斷期間我們可以提供默認(rèn)的處理邏輯(fallback),熔斷期間的調(diào)用都會(huì)返回 fallback 的結(jié)果,而不會(huì)再去嘗試本已非常不穩(wěn)定的服務(wù)。

需要注意的是,即使服務(wù)調(diào)用方引入了熔斷降級(jí)機(jī)制,我們還是需要在 HTTP 或 RPC 客戶(hù)端配置請(qǐng)求超時(shí)時(shí)間,來(lái)做一個(gè)兜底的防護(hù)。

冷系統(tǒng)預(yù)熱

當(dāng)系統(tǒng)長(zhǎng)期處于低水位的情況下,流量突然增加時(shí),直接把系統(tǒng)拉升到高水位可能瞬間把系統(tǒng)壓垮。我們可以利用 Guava 的 SmoothRateLimiter 或 Sentinel 的 Warm Up 流控模式,控制通過(guò)的流量緩慢增加,在一定時(shí)間內(nèi)逐漸增加到閾值上限,而不是在一瞬間全部放行。這樣可以給冷系統(tǒng)一個(gè)預(yù)熱的時(shí)間,避免冷系統(tǒng)被壓垮。

大數(shù)據(jù)中流控降級(jí)的示例分析

削峰填谷

請(qǐng)求的到來(lái)往往是沒(méi)有規(guī)律的。很多時(shí)候流量可能都集中于某幾秒的時(shí)間,而在接下來(lái)的一段時(shí)間內(nèi)都沒(méi)有很多請(qǐng)求。例如,某應(yīng)用的處理能力是每秒 10 個(gè)請(qǐng)求。在某一秒,突然到來(lái)了 30 個(gè)請(qǐng)求,而接下來(lái)兩秒,都沒(méi)有請(qǐng)求到達(dá)。在這種情況下,如果直接拒絕 20 個(gè)請(qǐng)求,應(yīng)用在接下來(lái)的兩秒就會(huì)空閑。所以,需要把請(qǐng)求突刺均攤到一段時(shí)間內(nèi),讓系統(tǒng)負(fù)載保持在請(qǐng)求處理水位之內(nèi),同時(shí)盡可能地處理更多請(qǐng)求,從而起到“削峰填谷”的效果。常見(jiàn)的場(chǎng)景為消息隊(duì)列消費(fèi)端處理消息的場(chǎng)景:

大數(shù)據(jù)中流控降級(jí)的示例分析

上圖中,紅色的部分代表超出消息處理能力的部分。觀察得出,消息突刺往往都是瞬時(shí)的、不規(guī)律的,其后一段時(shí)間系統(tǒng)往往都會(huì)有空閑資源。把紅色的那部分消息平攤到后面空閑時(shí)去處理,這樣既可以保證系統(tǒng)負(fù)載處在一個(gè)穩(wěn)定的水位,又可以盡可能地處理更多消息。我們可以利用 Leaky Bucket 算法 結(jié)合請(qǐng)求排隊(duì)來(lái)讓消息勻速消費(fèi),允許一部分消息排隊(duì)等待處理,超出最大等待時(shí)長(zhǎng)的消息直接拒絕處理。

Sentinel 提供了勻速排隊(duì)模式,可以很好地適用這種場(chǎng)景。

網(wǎng)關(guān)流控

網(wǎng)關(guān)作為流量的入口,會(huì)接收到大量的用戶(hù)請(qǐng)求。我們可以在網(wǎng)關(guān)層面,從流量入口處攔截激增的流量,防止下游服務(wù)被沖垮。網(wǎng)關(guān)流控常見(jiàn)的場(chǎng)景:

  • 限制某個(gè) API 的調(diào)用頻率,比如對(duì)外提供的 OpenAPI 每小時(shí)總調(diào)用量不超過(guò) 30000 次。

  • 針對(duì)每個(gè)請(qǐng)求的客戶(hù)端 IP、Header 或者 URL 參數(shù)進(jìn)行流控,比如限制每個(gè) IP 的調(diào)用頻次來(lái)進(jìn)行防刷。

  • 結(jié)合集群限流來(lái)限制某個(gè)下游服務(wù)的總調(diào)用量,這樣多余的流量就直接在網(wǎng)關(guān)層被拒絕了,而不會(huì)再打到應(yīng)用層。

對(duì)于使用了 Nginx 的場(chǎng)景,我們可以借助 Nginx 自帶的 ngx_http_limit_req_module 模塊來(lái)對(duì)經(jīng)過(guò) Nginx 的請(qǐng)求進(jìn)行限制;對(duì)于常用的 Java API Gateway,如 Spring Cloud Gateway 和 Zuul,我們可以利用 Sentinel 的網(wǎng)關(guān)流量控制特性,配置網(wǎng)關(guān)流控規(guī)則來(lái)針對(duì)每個(gè)不同路由、不同的請(qǐng)求屬性(如 HTTP Header、URL 參數(shù)等)進(jìn)行流量控制。

流控降級(jí)規(guī)則的配置

需要注意的是,限流降級(jí)的配置是需要結(jié)合容量規(guī)劃、依賴(lài)梳理來(lái)做的。我們可以借助 JMeter 或 阿里云 PTS 等壓測(cè)工具對(duì)我們的服務(wù)進(jìn)行全鏈路壓測(cè),了解每個(gè)服務(wù)的最大承受能力,來(lái)確定流控和熔斷降級(jí)的閾值。同時(shí),業(yè)務(wù)系統(tǒng)需要具備實(shí)時(shí)監(jiān)控的能力,以便實(shí)時(shí)地根據(jù)流量情況做出相應(yīng)的限流降級(jí)策略調(diào)整。

以上是“大數(shù)據(jù)中流控降級(jí)的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI