Spring-cloud微服務實戰【七】:服務熔斷與降級hystrix

  在以前的文章中,咱們前後介紹了eureka,ribbon,feign,使用eureka集羣的方式來保證註冊中心的高可用,在eureka中使用ribbon進行負載均衡,使用feign接口替換手動編碼請求接口的代碼,整個微服務看似基本完成了,那是否有繼續值得優化的地方呢?答案確定是有的,而且是整個微服務最重要的一環,那就是服務的熱熔斷與降級,那爲何服務熔斷與降級是最重要的一環呢?咱們先來看一下服務雪崩的概念.git

服務雪崩

  所謂服務雪崩,是微服務系統中特有的概念,不瞭解服務雪崩的概念的童鞋,初一聽服務雪崩,確定會聯想到緩存雪崩,所謂緩存雪崩,即大量緩存在同一時間過時,致使大量請求不走緩存而進行數據庫訪問,數據庫瞬時壓力暴增,致使數據庫宕機.通常咱們的解決方案無非有幾點:
1.爲不一樣的緩存設置不一樣的過時時間.
2.熱點數據永不過時.
3.緩存預熱.
  咱們之因此要預防緩存雪崩,從系統架構五個方面(高性能/高可用/伸縮性/擴展性/安全性)來說,是保證系統的高性能以及保護數據庫,而咱們說要預防服務雪崩,是爲了保證整個微服務系統的可用性,讓咱們用一張圖來講說明:
filegithub

  假設在一個電商微服務系統中,有用戶服務,訂單服務,產品服務,物流服務等服務,用戶服務調用訂單服務,訂單服務調用產品服務,產品服務調用物流服務,若是沒有考慮服務的熔斷與降級,假如在產品服務調用物流服務的時候,物流服務自己出問題了返回了錯誤或者是網絡波動致使請求超時,則產品服務會報錯,從而影響訂單服務跟着報錯,層層返回,直到最頂層的服務,這樣就致使了一個微服務自身的問題影響了整個微服務系統級聯報錯,這就是所謂的服務雪崩,極端狀況下,可能致使幾個甚至整個微服務系統所有宕機,這對於現代微服務系統來講,是沒法忍受的,所以,咱們須要進行服務的熔斷與降級.
  須要注意的是,服務的熔斷與降級是兩個概念,通常而言,所謂服務熔斷,是對服務提供方而言,當服務提供方沒法調用的時候須要被熔斷,而降級是對服務消費方而言,當服務提供方沒法正常提供服務時,消費方須要降級處理.spring cloud中對服務的熔斷和降級是使用hystrix,接下來,讓咱們詳細瞭解一下hystrix.spring

服務熔斷與降級hystrix

  spring cloud中使用hystrix進行服務的熔斷和降級,hystrix翻譯成中文是豪豬的意思,它是Netflix開源的一款針對分佈式系統進行服務熔斷與降級的框架.那麼咱們如何使用呢?讓咱們直接用代碼來演示一下:
  把以前咱們的項目dhp-micro-service-producer複製一份爲dhp-micro-service-producer-hystrix:
file
  將之加入父項目:
file數據庫

  老規矩,三個步驟,首先新增maven依賴:
file緩存

  而後修改代碼:
file安全

  其中@HystrixCommand的做用是指定一個熔斷方法,當有該註解的方法拋出異常的時候,會調用fallbackMethod指定的方法,該方法須要咱們本身根據業務須要來完成.須要注意的是,方法的入參和返回值都必需要和原始方法保持一致.
  修改一下配置文件,注意eureka註冊中心的地址和端口號,我這裏修改端口號爲7301:
file網絡

  最後修改啓動類,增長對hystrix的支持:
file架構

  而後啓動來訪問試一試,注意若是啓動報錯,看看是否eureka-server未啓動,但這並不影響咱們的測試,因爲咱們在producer項目中的product信息是使用代碼方式來mock數據庫操做:
fileapp

  總計只有6條數據,所以ID>6均查不出數據,返回product=null,就會觸發咱們設置的降級方法,所以訪問試一試:
file負載均衡

  說明咱們的服務提供方在服務出現異常時的熔斷方法已經成功使用了,但這還不夠,在某些狀況下,服務的提供方並無問題,可是可能因爲網絡緣由致使消費方並不能成功調用到提供方的接口,此時服務提供方的任何處理都是毫無心義的,所以咱們須要在消費者端進行服務降級.
  因爲咱們以前使用feign進行接口代理,而feign中已經集成了hystrix,所以咱們須要改造consumer端代碼:
  首先在feign代理接口中新增fallbackFactory指定降級服務的類:
file

  而後實現該類,該類須要實現FallbackFactory接口的create方法,返回一個泛型指定的服務,而且實現該指定接口中的全部方法的降級處理:
file

  而後咱們能夠驗證一下:首先啓動eureka-server,而後啓動producer,將producer註冊到eureka:
file
  能夠看到,咱們修改端口號爲7301的producer[dhp-micro-service-producer-hystrix]已經成功註冊到eureka,而後再啓動consumer[dhp-micro-service-consumer-feign],我修改端口號爲7005,而且還須要開啓feign.hystrix.enabled=true,默認是false:
file

  啓動成功後,訪問一下試一試:
file

  當咱們id=1時,能夠成功獲取結果,再試一試當ID>6時的狀況:
file

  從描述能夠看到,這是執行了producer[dhp-micro-service-producer-hystrix]的熔斷方法,那咱們如何來驗證消費者端的降級方法呢?首先須要關閉eureka-server的自我保護功能,而且設置10秒自檢一次,剔除無效的服務:
file

  那麼如何算無效呢?這須要服務提供方進行設置,修改producer[dhp-micro-service-producer-hystrix]發送心跳時間以及服務過時時間,以便儘快讓eureka-server剔除producer:
file

  這裏咱們爲了快速讓eureka-server剔除producer,設置5秒(默認值爲30秒)發送1次心跳,而且告訴eureka-server,假如15秒(默認值爲90秒,通常爲心跳間隔時間的3倍)內沒有發送任何心跳,則eureka-server將producer剔除,此時,eureka-server主動失效檢測時間爲10秒,則當咱們中止producer後最多25秒eureka-server會將producer剔除,此時再訪問consumer:
file

  能夠看到,這是執行了咱們consumer的降級方法,自此hystrix在服務提供方和消費方的配置都完成了,是否是很簡單?接下來,讓咱們再瞭解一下hystrix的儀表盤dashboard.

HystrixDashboard

  Dashboard(儀表盤)是hystrix提供的一種用於服務監控的功能,能夠利用它對某一個微服務進行監控,讓咱們來試一試,首先新建一個module[dhp-micro-service-hystrix-dashboard]:
file
  而後將之加入父項目:
file

  接下來新增maven依賴:
file

  而後配置文件修改服務端口號:
file

  而後啓動類新增對dashboard的支持:
file

  啓動起來看一下:
file

  那麼該如何使用呢?首先,須要確保被監控的服務有健康檢查的依賴,好比咱們對producer[dhp-micro-service-producer-hystrix]進行監控,則須要確保producer的maven配置中有健康檢查的相關依賴:
file

  而且還須要相關的配置:
file

  而後啓動producer,而且在hystrix dashboard中輸入對應的producer的地址,則就能監控到全部的對該地址的訪問:
file

  此時再訪問該producer的相關接口,就能看到相關統計信息了:
file

  至於其中每項數據的含義,我相信確定難不倒各位廣大童鞋,畢竟有問題找度娘,你們都知道,有條件就Google,沒有任何問題能難倒咱們.

Turbine

  細心的同窗會發現,以前咱們在hystrix-dashboard的首頁上看到了這麼一行提示:
file

  翻譯一下,就是告訴咱們若是是使用turbine的方式,監控地址的格式是turbine-hostname:port/turbine.stream,若是是單一的hystrix-app的方式,地址格式是hystrix-app:port/actuator/hystrix.stream,咱們以前就是使用的單一的這種方式,那麼turbine又是什麼呢?

  咱們在上面說到,dashboard只能對某一個微服務進行監控,但實際狀況是一個微服務生產系統遠遠不止一個微服務,咱們須要對全部的微服務都進行監控,而dashboard顯然沒法知足咱們的需求,而turbine則能夠,所以turbine的做用就是能夠對多個微服務同時進行監控.爲了方便演示turbine對多個微服務的監控,咱們新建一個module[dhp-micro-service-user-hystrix]:
file

  而後加入父項目:
file

  而後老規矩,三個步驟,先配置maven依賴:
file

  而後再配置application.properties:
file

  相關配置具體的含義就不在多說了,以前的文章已經講得很詳細了,接着修改主類:
file

  而後進行編碼:
file

  相關代碼和producer相似,而後啓動eureka-server,再啓動user和producer:
file

  能夠看到兩個服務都已經註冊到eureka了,而後使用dashboard測試一下:
file

  沒有問題,說明能夠,接下來,咱們使用turbine同時監控producer和user服務,爲了便於和以前的dashboard比較,咱們新增一個turbine module[dhp-micro-service-turbine-dashboard]:
file

  將之加入父項目:
file

  而後老規矩,首先配置maven依賴:
file

  而後配置application.properties:
file

  其中最重要的就是須要配置turbine相關信息,app-config標識須要監控的服務,多個用逗號隔開,而且從名字咱們能夠看出就是eureka中註冊的服務的服務名:
file

  新增主類配置:
file

  而後先啓動eureka-server,再啓動user[dhp-micro-service-user-hystrix]和producer[dhp-micro-service-producer-hystrix]兩個服務,再啓動dashboard[dhp-micro-service-hystrix-dashboard],最後啓動turbine[dhp-micro-service-turbine-dashboard],而後訪問dashboard[dhp-micro-service-hystrix-dashboard],並監控turbine的地址:
file

  而後分別請求user和producer:
file
file

  而後看一下hystrix-dashboard:
file

  發現只監控到了userController,可是並無監控到ProducerController,這是爲何呢?是咱們配置不對嗎?彆着急,咱們來看一下控制檯的信息:
file
file

  提示信息告訴咱們,有一個鏈接被拒絕,所以放棄turbine對其的監控,失敗的地址是192.168.1.13:7301,能夠看出這是咱們的producer服務的地址,另外提示信息中status401,error和message都提示咱們,未受權的登陸,回憶一下,以前咱們的producer項目引入了dhp-micro-service-auth進行安全驗證,須要用戶名和密碼,所以咱們找到了緣由:登陸producer時未受權,致使監控失敗,那這該如何解決呢?很遺憾,turbine既能監控全部服務都有密碼的情形,也能監控全部服務都沒有密碼的情形,可是對於有些服務有密碼,而有些服務沒有密碼的情形,turbine就無能爲力了,若是實在由於生產須要要適配,咱們只能經過修改dhp-micro-service-auth的方式,來讓相應的服務取消對/actuator/hystrix.stream與/turbine.stream這兩個地址的密碼驗證:
file

  此時再重啓一下producer,而後再次訪問user和producer,再看一下dashboard:
file

  此時producerController和UserController均成功被turbine監控了.

  回顧一下,在本文咱們介紹了spring-cloud斷路器hystrix以及對hystrix的單個服務監控hystrix-dashboard以及對多個服務監控的turbine,下一篇文章,咱們繼續介紹網關zuul,敬請期待!

  本文的github地址

本文由博客一文多發平臺 OpenWrite 發佈!

相關文章
相關標籤/搜索