跟我學Spring Cloud(Finchley版)-12-微服務容錯三板斧

至此,咱們已實現服務發現、負載均衡,同時,使用Feign也實現了良好的遠程調用——咱們的代碼是可讀、可維護的。理論上,咱們如今已經能構建一個不錯的分佈式應用了,但微服務之間是經過網絡通訊的,網絡可能出問題;微服務自己也不可能100%可用。spring

如何提高應用的可用性呢?這是咱們必須考慮的問題——服務器

舉個例子:某大型系統中,服務A調用服務B,某個時刻,微服務B忽然崩潰了。微服務A中,依然有大量請求在請求B,若是沒有任何措施,微服務A極可能很快就會被拖死——由於在Java中,一次請求每每對應着一個線程,若是不作任何措施,那意味着微服務A請求B的線程要等Feign Client/RestTemplate超時纔會釋放(這個時間通常很是長,長達幾十秒),因而就會有大量的線程被阻塞,而線程又對應着計算資源(CPU/內存),因而乎,大量的資源被浪費,而且越積越多,最終服務器終於沒有資源給微服務A浪費了,微服務A也掛了。網絡

所以,在大型應用中,微服務之間的容錯必不可少,下面來討論如何實現微服務的容錯。併發

應用容錯三板斧

超時機制

超時機制你懂的,配置一下超時時間,例如1秒——每次請求在1秒內必須返回,不然到點就把線程掐死,釋放資源!負載均衡

思路:一旦超時,就釋放資源。因爲釋放資源速度較快,應用就不會那麼容易被拖死。分佈式

艙壁模式

有興趣的能夠先了解一下船艙構造——通常來講,現代的輪船都會分不少艙室,艙室之間用鋼板焊死,彼此隔離。這樣即便有某個/某些船艙進水,也不會影響其餘艙室,浮力夠,船不會沉。微服務

軟件世界裏的倉壁模式能夠這樣理解:M類使用線程池1,N類使用線程池2,彼此的線程池不一樣,而且爲每一個類分配的線程池較小,例如coreSize=10。舉個例子:M類調用B服務,N類調用C服務,若是M類和N類使用相同的線程池,那麼若是B服務掛了,M類調用B服務的接口併發又很高,你又沒有任何保護措施,你的服務就極可能被M類拖死。而若是M類有本身的線程池,N類也有本身的線程池,若是B服務掛了,M類頂可能是將本身的線程池佔滿,不會影響N類的線程池——因而N類依然能正常工做,線程

思路:不把雞蛋放在一個籃子裏。你有你的線程池,我有個人線程池,你的線程池滿了和我不要緊,你掛了也和我不要緊。設計

斷路器

現實世界的斷路器你們確定都很瞭解,每一個人家裏都會有斷路器。斷路器實時監控電路的狀況,若是發現電路電流異常,就會跳閘,從而防止電路被燒燬。blog

軟件世界的斷路器能夠這樣理解:實時監測應用,若是發如今必定時間內失敗次數/失敗率達到必定閾值,就「跳閘」,斷路器打開——此時,請求直接返回,而不去調用本來調用的邏輯。

跳閘一段時間後(例如15秒),斷路器會進入半開狀態,這是一個瞬間態,此時容許一次請求調用該調的邏輯,若是成功,則斷路器關閉,應用正常調用;若是調用依然不成功,斷路器繼續回到打開狀態,過段時間再進入半開狀態嘗試——經過」跳閘「,應用能夠保護本身,並且避免浪費資源;而經過半開的設計,可實現應用的「自我修復「。

TIPS:

斷路器的提出人也是Martin Fowler,」微服務「這個名詞被普遍瞭解,也和他有密不可分的關係。Martin Fowler的博客:http://www.martinfowler.com

斷路器狀態轉換可以下圖所示:

斷路器狀態轉換示意圖

本文較短,但相信已經用通俗的語言講解了常見的幾種容錯機制——目前Spring Cloud生態中,支持的斷路器有:Hystrix、Resilience4J、Alibaba Sentinel,雖然彼此實現有較大差別,但本質原理是相通的。

本節是斷路器的基石,在理解原理後,你會發現用不一樣的實現只是使用的依賴和註解不大同樣而已。

下一節,將着重講解如何使用Hystrix實現微服務的容錯。

本文首發

http://www.itmuch.com/spring-cloud/finchley-12/

乾貨分享

全是乾貨

相關文章
相關標籤/搜索