前言
從PC互聯(lián)網(wǎng)到移動互聯(lián)網(wǎng),B/S架構(gòu)演化為多端/S架構(gòu)。后端服務SOA模式下的重服務或單服務架構(gòu),逐漸按功能模塊被切分成微服務架構(gòu)(延伸閱讀《軟件工程和架構(gòu)發(fā)展簡史》)。微服務架構(gòu)確實能解決單服務架構(gòu)的許多頑疾,比如代碼維護難、部署不靈活、穩(wěn)定性不高、無法快速擴展等。但隨著微服務模塊的與日俱增,它又帶來了一些新的問題需要解決。針對這些問題,Spring Cloud提供了一整套微服務實施方案,包括服務發(fā)現(xiàn)、分布式配置、客戶端負載均衡、服務容錯保護、API網(wǎng)關(guān)、安全、分布式服務跟蹤等。今天就談一下微服務容錯保護中的三個重要概念:服務降級、服務限流以及服務熔斷。還有緩存和負載均衡回頭再說
降級、限流以及熔斷都是解決服務之間RPC過程出現(xiàn)的異常問題,避免因局部服務問題造成全局服務雪崩。服務間的RPC過程可以簡單描述為C?S。那么這個過程可能會出現(xiàn)哪些異常情況?降級、限流以及熔斷各自解決的是什么異常問題,它們又是如何解決的?
限流
C?S 的異常問題:C的請求太多,超出S的服務能力,導致S不可用。DoS攻擊就是根據(jù)此原理,耗盡被攻擊對象的資源,讓目標系統(tǒng)無法響應甚至崩潰。解決方案:S對C限流,保護S的服務資源。
限流通常在網(wǎng)關(guān)或網(wǎng)絡層面實施。對各類請求設(shè)置最高的QPS閾值,當請求高于閾值時直接阻斷。常用的限流算法有滑動計數(shù),漏斗限流和令牌桶限流三種。
滑動計數(shù)限流:按時間片(比如1秒)定義滑動窗口,計數(shù)器記錄當前窗口的請求次數(shù),達到閾值就限流,窗口滑動后計數(shù)器歸零??刹捎醚h(huán)隊列數(shù)據(jù)結(jié)構(gòu)實現(xiàn)。
漏斗限流:維護一個隊列,所有請求進隊列,按FIFO服務,隊滿溢出則丟棄請求。
令牌桶限流:按固定速率往桶中存入令牌,服務前先從桶中取令牌,取到令牌才服務。
降級
C?S的異常問題:S自身出現(xiàn)異常,或者由于資源有限需要對部分C請求故意表現(xiàn)為異常(類似限流),為了不影響其他服務功能,主動關(guān)閉服務的一些功能。
降級的反義詞是升級,升級需要代碼開發(fā),降級類似于把部分代碼注釋掉,犧牲部分功能。這要求S在實現(xiàn)時,需要具備感知異常的能力,并對關(guān)鍵邏輯實現(xiàn)開關(guān)控制。實際場景中,對異常的『感知』通常由熔斷器實現(xiàn)。
熔斷
C?S的異常問題:C發(fā)現(xiàn)S出現(xiàn)異常(比如大量超時),主動出擊,暫停對S的請求。
C對S熔斷后,那么原本需要調(diào)用S實現(xiàn)的邏輯怎么辦呢?可以用mock數(shù)據(jù)、緩存數(shù)據(jù)、缺省數(shù)據(jù)等替代,或者干脆就是拋異常返回錯誤信息。此時,如果C也是一個服務,它相當于做了服務降級。所以我們經(jīng)??吹椒杖蹟嗪头战导壱黄鸪霈F(xiàn)(Hystrix的斷路器在實現(xiàn)時就是把熔斷和降級方案打包實現(xiàn)的)。但本質(zhì)上它們不是一回事,降級發(fā)生在S,熔斷發(fā)生在C。之所以配合實現(xiàn),是因為許多微服務模塊同時承擔C和S兩種角色。
熔斷的設(shè)計有兩個關(guān)鍵點:① 判斷何時熔斷,② 何時從熔斷狀態(tài)恢復。
判斷何時熔斷:通常使用無鎖循環(huán)隊列計數(shù)來實現(xiàn)。C對每次請求S的正常、異常(失敗、拒絕、超時)返回計數(shù),當異常返回次數(shù)超過設(shè)定閾值時進行熔斷。
何時從熔斷狀態(tài)恢復:處于熔斷狀態(tài)時,C每隔一段時間(比如5秒),允許部分請求通過,若這部分請求正常返回,就恢復熔斷。
總結(jié)
降級、限流以及熔斷都是解決服務之間RPC過程的異常問題,保證服務穩(wěn)定性的手段。降級和限流發(fā)生在S端,熔斷發(fā)生在C端。在實際場景中,它們通常會配合實現(xiàn),特別是熔斷和降級。熔斷決定何時降級,降級是服務在熔斷狀態(tài)下的對外表現(xiàn)。Spring Cloud全家桶中的Hystrix就是一個優(yōu)秀的熔斷&降級組件。