Spring Cloud -- Hystrix服務降級(Service端)
前言
上一篇分享完Openfeign後,相信大家的MicroService已經越來越多了,接下來要為大家分享Spring Cloud的下一個功能:Hystrix。不過在分享前,我們需要先探討一個分布式系統必須面臨的問題。
分布式系統所面臨的問題
首先,我們先來看下圖
上圖是一個微服務做調用的示意圖,從圖中我們可以看到User端在調用微服務時,需同時調用不只一個Service,如果都能順利的正常調用,則可以完成本次的Request,這就是所謂微服務的"扇出",不過一旦扇出中間有一個Service出現超時或是不可用時,對該Service的調用就會占用越來越多,進而引發系統崩潰,造成所謂的"雪崩效應"。
Hystrix服務
為了避免系統產生雪崩效應,應將出錯的Service與正常的Service做出隔離處置,並維持整個分布式系統仍然能夠運行,Hystrix就是一個用於處理分布式系統的延遲及容錯的開源庫,在分布式系統中,有非常多的依賴不可避免的會調用失敗(Time out、Exception),Hyxtrix能夠保證在一個依賴出問題的狀況下,不會導致整體服務失敗,避免服務雪崩,提高分布式系統的彈性。
Hystrix的原理就像是一種"熔斷保險絲"開關裝置,在發生錯誤時,向調用方返回一個符合預期的、可處理的回應,而非讓系統長時間等待或拋出無法處理的異常,保證了後台服務端的Thread不會被長時間占用、不必要的佔用,避免了一個故障導致整個分布式系統的服務中斷,進而服務雪崩。
Hystrix的服務共分三種:服務降級(fallback)、服務熔斷(break)、服務限流(flow),接下來會一一的與大家做分享。
Hystrix服務降級(fallback)
服務降級會出現的時機有:
1. 程序運行異常
2. 超時(Time out)
3. 服務熔斷觸發服務降級
4. 執行緒池/信號量打滿
接下來,我們開始構建一個服務來演示
1. 首先,我們將eureka的7001做一個修正,使他暫時成為單機版的功能
2. 新建一個project,在pom中加入我們Hystrix的包
3. 在resources中建立application.yml,內容如下
4. 建立入口class
5. 接下來,我們做一個service,裡面有兩個方法,分別是正常執行的paymentInfo_OK及會出現錯誤的paymentInfo_TimeOut
6. 做一個controller來返回測試的值
7. 執行Eureka7001、PaymentHystrix8001,並在網頁上確認Eureka有註冊成功 (http://eureka7001.com:7001/)
8. 先試試正常程序 http://localhost:8001/payment/hystrix/ok/31 顯示如下
9. 再來,我們測試需要執行3秒的程序 http://localhost:8001/payment/hystrix/timeout/31,也能順利執行
10. 再來,我們使用Jmeter這個工具來做壓力測試,使用方式剛剛好我們昕力大學有XDDDD,附上連結 https://www.tpisoftware.com/tpu/articleDetails/1705,我們設定200個Thread、共執行20000次。
11. 執行之後我們回到 http://localhost:8001/payment/hystrix/ok/31,會發現執行時間從本來秒回,變成需轉很多圈圈才回應,這是因為tomcat中默認的執行緒池已被打滿,沒有多餘的執行緒來分憂解勞,當然,這只是自測,如果更多Request(加入消費端),將會讓這個速度拖得更慢,形成Timeout。
為了避免上述的事情發生,我們必須要在狀況發生的時候讓服務降級,服務降級有3個時機點:
(1). Service端Timeout,Client端需服務降級
(2). Service端當機、Client端需服務降級
(3). Service端ok,但Client端出現故障或Timeout,需服務降級
因此,我們需要在程式中加一些東西,請繼續往下看~
12. 回到hystrix-payment8001,我們在PaymentService中寫一個 paymentInfo_TimeOutHandler method,代表如果發生錯誤時的回應,再來在timeout method中加上一個 @HystrixCommand ,這個設定的意思是當timeout method發生錯誤時,Hystrix將會自動執行 paymentInfo_TimeOutHandler 這隻程式,不會等待造成系統資源浪費導致崩潰,如下圖(我們將timeNumber設定為5秒來測試):
13. PaymentHystrix的入口部份我們加上 @EnableCircuitBreaker 來使 hystrix產生作用
14. 完成後啟動Eureka7000、PaymentHystrixMain8001 ,我們的業務邏輯為超過3秒即判斷為Timeout,進入 http://localhost:8001/payment/hystrix/timeout/31,可以發現當API執行超過3秒後,自動丟回 paymentInfo_TimeOutHandler 的方法,使系統保持運作正常。
以上,就是我們這次分享的 Hystrix的服務降級(Service端),下一篇我們會繼續探討Hystrix的服務降級在Client端如何配置,文章中若有疏漏,也歡迎各位前輩不吝指教,謝謝大家~
參考文獻
尚硅谷Spring Cloud教程
https://github.com/Netflix/Hystrix/wiki/How-To-Use