微服務架構如何保障雙11狂歡下的99.99%高可用

歡迎關注微信公衆號:石杉的架構筆記(id:shishan100)mysql

個人新課**《C2C 電商系統微服務架構120天實戰訓練營》在公衆號儒猿技術窩**上線了,感興趣的同窗,能夠點擊下方連接瞭解詳情:面試

《C2C 電商系統微服務架構120天實戰訓練營》redis

目錄sql

1、概述緩存

2、業務場景微信

3、線上經驗—如何設置Hystrix線程池大小markdown

4、線上經驗—如何設置請求超時時間架構

5、問題解決併發

6、總結app

1、概述

上一篇文章講了一個朋友公司使用Spring Cloud架構遇到問題的一個真實案例,雖然不是什麼大的技術問題,但若是對一些東西理解的不深入,還真會犯一些錯誤。

若是沒看過這篇的朋友,建議先看看:【雙11狂歡的背後】微服務註冊中心如何承載大型系統的千萬級訪問? 由於本文的案例背景會基於上一篇文章。

這篇文章咱們來聊聊在微服務架構中,到底如何保證整套系統的高可用?

其實排除掉一些基礎設施的故障,好比說Redis集羣掛了,Elasticsearch集羣故障了,MySQL宕機了。

微服務架構本身自己最最核心的保障高可用的措施,就是兩個:

  1. 一個是基於Hystrix作資源隔離以及熔斷;

  2. 另外一個是作備用降級方案。

若是資源隔離和降級都作的很完善,那麼在好比雙11的這種高併發場景下,雖然可能會出現個別的服務故障,可是絕對是不會蔓延到整個系統所有宕機的。

這裏你們若是忘了如何基於hystrix作資源隔離、熔斷以及降級的話,能夠回顧一下文章:《 拜託!面試請不要再問我Spring Cloud底層原理 》

2、業務場景

好的,那咱們這就來深刻的分析一下,在實際生產系統中,hystrix的線程池以及超時時間,這兩個參數應該如何根據系統的負載設置到最佳的狀態?

你們首先回顧下面這張圖,這是上篇文章中說到的一個公司的系統。

核心服務A調用了核心服務B和C,在覈心服務B響應過慢時,會致使核心服務A的某個線程池所有卡死。

可是此時由於你用了hystrix作了資源隔離,因此核心服務A是能夠正常調用服務C的,那麼就能夠保證用戶起碼是可使用APP的部分功能的,只不過跟服務B關聯的頁面刷不出來,功能沒法使用罷了。

固然這種狀況在生產系統中,是絕對不被容許的,因此你們千萬讓上述狀況發生。

在上一篇文章中,咱們最終把系統優化成了下圖這樣,要保證一個hystrix線程池能夠輕鬆處理每秒鐘的請求,同時還有合理的超時時間設置,避免請求太慢卡死線程。

3、線上經驗—如何設置Hystrix線程池大小

好,如今問題來了,在生產環境中,咱們到底應該如何設置服務中每一個hystrix線程池的大小,以及如何設置超時時間呢?

下面就是咱們線上大量系統優化後的生產經驗總結:

假設你的服務A,每秒鐘會接收30個請求,同時會向服務B發起30個請求,而後每一個請求的響應時長經驗值大概在200ms,那麼你的hystrix線程池須要多少個線程呢?

計算公式是:30(每秒請求數量) * 0.2(每一個請求的處理秒數) + 4(給點緩衝buffer) = 10(線程數量)。

若是你們對上述公式存在疑問,不妨反過來推算一下,爲何10個線程能夠輕鬆抗住每秒30個請求?

一個線程200毫秒能夠執行完一個請求,那麼一個線程1秒能夠執行5個請求,理論上,只要6個線程,每秒就能夠執行30個請求。

也就是說,線程裏的10個線程中,就6個線程足以抗住每秒30個請求了。剩下4個線程都在玩兒,空閒着。

那爲啥要多搞4個線程呢?很簡單,由於你要留一點buffer空間。

萬一在系統高峯期,系統性能略有降低,此時很多請求都耗費了300多毫秒才執行完,那麼一個線程每秒只能處理3個請求了,10個線程剛恰好勉強能夠hold住每秒30個請求。因此你必須多考慮留幾個線程。

老規矩,給你們來一張圖,直觀的感覺一下。

4、線上經驗—如何設置請求超時時間

接着來,那麼請求的超時時間設置爲多少?答案是300毫秒。

爲啥呢?很簡單啊,兄弟!若是你的超時時間設置成了500毫秒,想一想可能會有什麼後果?

考慮極端狀況,若是服務B響應變慢,要500毫秒才響應,你一個線程每秒最多隻能處理2個請求了,10個線程只能處理20個請求。

而每秒是30個請求過來,結局會如何?我們回看一下第一張圖就知道了,大量的線程會所有卡死,來不及處理那麼多請求,最後用戶會刷不出來頁面。

仍是有點不理解?再給你一張圖,讓你感覺一下這個不合理的超時時間致使的問題!

若是你的線程池大小和超時時間沒有配合着設置好,極可能會致使服務B短暫的性能波動,瞬間致使服務A的線程池卡死,裏面的線程要卡頓一段時間才能繼續執行下一個請求。

哪怕服務B的接口性能恢復到200毫秒之內了,服務A的線程池裏卡死的情況也要好一下子才能恢復過來。你的超時時間不合理的設置的越長,好比設置1秒、2秒,那麼這種卡死的狀況就須要越長的時間來恢復。

因此說,此時你的超時時間就得設置成300毫秒,保證一個請求300毫秒內執行不完,立馬超時返回。

這樣線程池裏的線程不會長時間卡死,能夠有條不紊的處理多出來的請求,大不了就是300毫秒內處理不完當即超時返回,可是線程始終保持能夠運行的狀態。

這樣當服務B的接口性能恢復到200毫秒之內了,服務A的線程池裏的線程很快就能夠恢復。

這就是生產系統上的hystrix參數設置優化經驗,你必須考慮到各類參數應該如何設置。

不然的話,極可能會出現上文那樣的狀況,用了高大上的Spring Cloud,結果跟黑盒子同樣,莫名其妙系統故障,各類卡死,宕機什麼的。

5、問題解決

好了,咱們繼續。若是如今這套系統每秒有6000請求,而後核心服務A一共部署了60臺機器,每臺機器就是每秒會收到100個請求,那麼此時你的線程池須要多少個線程?

很簡單了,10個線程抗30個請求,30個線程抗100請求,差很少了吧。

這個時候,你知道你的服務A的線程池,調用服務B的那個線程池,應該分配多少線程了吧?超時時間如何設置應該也知道了!

其實這個東西不是固定死的,可是你要知道他的計算方法,根據服務的響應時間、系統高峯QPS、有多少臺機器,來計算出來,線程池的大小以及超時時間!

設置完這些以後,就應該要考慮服務降級的事情了。

若是你的某個服務掛了,那麼你的hystrix會走熔斷器,而後就會降級,你須要考慮到各個服務的降級邏輯。

舉一些常見的例子:

  • 若是查詢數據的服務掛了,你能夠查本地的緩存

  • 若是寫入數據的服務掛了,你能夠先把這個寫入操做記錄日誌到好比mysql裏,或者寫入MQ裏,後面再慢慢恢復

  • 若是redis掛了,你能夠查mysql

  • 若是mysql掛了,你能夠把操做日誌記錄到es裏去,後面再慢慢恢復數據。

具體用什麼降級策略,要根據業務來定,不是一成不變的。

6、總結

總結一下,排除那些基礎設施的故障,你要玩兒微服務架構的話,須要保證兩點:

  1. 首先你的hystrix資源隔離以及超時這塊,必須設置合理的參數,避免高峯期,頻繁的hystrix線程卡死

  2. 其次,針對個別的服務故障,要設置合理的降級策略,保證各個服務掛了,能夠合理的降級,系統總體可用!

若有收穫,請幫忙轉發,您的鼓勵是做者最大的動力,謝謝!

一大波微服務、分佈式、高併發、高可用原創系列文章正在路上:

****《兄弟,用大白話告訴你小白都能看懂的Hadoop架構原理》**,**敬請期待

****《大規模集羣下Hadoop的NameNode如何承載高併發訪問》**,**敬請期待

歡迎掃描下方二維碼,持續關注:

![](https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2018/11/12/167088310d1d57b1~tplv-t2oaga2asx-image.image)

石杉的架構筆記(id:shishan100)

十餘年BAT架構經驗傾囊相授

相關文章
相關標籤/搜索