實戰系列-Spring Cloud微服務中三把利器Feign、Hystrix、Ribbon

導語
  在之前的分享中分享過關於Fegin的底層實現原理,以及Spring Cloud OpenFegin的啓動原理。在這次的分享中主要總結一下Spring Cloud 微服務架構的三把利器。對於Fegin、Hystrix、Ribbon三個組件來說它們之間是什麼樣的關係。怎麼樣綜合使用等這些問題就是這次分享的內容

Fegin介紹

GitHub地址 https://github.com/OpenFeign/feign.git

  首先通過上次的分析可以知道Fegin是通過Java 語言編寫的基於HttpClient的綁定器,在Spring Cloud微服務架構中主要的功能就是實現聲明式服務調用。Fegin可以請求其他服務定義的接口,實現服務之間的調用,通過Fegin調用客戶端不需要在去編寫多餘Http請求服務接口,如果在調用過程中出現錯誤還可以調用其實現類來返回。

  Feign是一個聲明式的web service客戶端,它使得編寫web service客戶端更爲容易。創建接口,爲接口添加註解,即可使用Feign。Feign可以使用Feign註解或者JAX-RS註解,還支持熱插拔的編碼器和解碼器。Spring Cloud爲Feign添加了Spring MVC的註解支持,並整合了Ribbon和Eureka來爲使用Feign時提供負載均衡。

Ribbon介紹

GitHub地址 https://github.com/Netflix/ribbon.git

  提到Ribbon最常聽到的一個名詞就是客戶端負載均衡,就是說將服務端的負載均衡放到了客戶端來實現。對於服務端來說可以啓動多個不同端口的實例,通過客戶端負載均衡來去調用這些實例。

  Ribbon是Netflix發佈的開源項目,主要功能是提供客戶端的軟件負載均衡算法,將Netflix的中間層服務連接在一起。提供了客戶端組件的一系列完善的配置項,如連接超時,重試等。也就是說通過配置的方式可以列舉出需要負載的後端所有的服務,Ribbon會通過對應的策略(輪詢、權重、隨機等)來去連接這些機器。當然在這些策略與實際業務不符合的時候還可以通過自定義的負載均衡算法來實現調用。因爲這些工作都是由客戶端來完成,所以被稱爲是客戶端的負載均衡器。

  Ribbon的工作原理,Ribbon工作時分爲兩步:

  • 第一步 先選擇 Eureka Server, 它優先選擇在同一個Zone且負載較少的Server;
  • 第二步 再根據用戶指定的策略,在從Server取到的服務註冊列表中選擇一個地址。Ribbon提供了多種策略,例如輪詢、隨機、根據響應時間加權等

Hystrix介紹

GitHub地址 https://github.com/Netflix/Hystrix.git

  從GitHub地址來看這個也是Netflix的項目,也是由Java來編寫 。Hystrix作爲熔斷流量控制在客戶端實現,使用的時候,在方法上進行註解,當請求出錯時可以調用註解中的方法返回。
  Hystrix熔斷器,容錯管理工具,通過熔斷機制控制服務和第三方庫的節點也就是其他業務之間的調用。從而對延遲和故障提供更強大的容錯能力。並且在Spring Cloud Hystrix中實現了線程隔離、斷路器等一系列的服務保護功能。它也是基於Netflix的開源框架 Hystrix實現的,該框架目標在於通過控制那些訪問遠程系統、服務和第三方庫的節點,從而對延遲和故障提供更強大的容錯能力。Hystrix具備了服務降級、服務熔斷、線程隔離、請求緩存、請求合併以及服務監控等功能。

三者關係

  在開發過程中,如果微服務項目加上了spring-cloud-starter-netflix-hystrix依賴,那麼,feign會通過代理模式, 自動將所有的方法用 hystrix 進行包裝。在對Feign進行包裝的時候也提到過動態代理。

  在Spring Cloud技術體系之下Feign可以提供聲明式的服務調用。在這個服務調用的過程中會通過Ribbon從Eureka註冊中獲取到對應的服務器列表出來,在後續的網絡請求調用的過程中Ribbon的作用就是負責整體的負載均衡。將調用通過負載的形式調用到不同的實例上。這也就是實現了Spring Cloud的服務發現以及負載均衡的內容。

  那麼在這個過程中好像沒有Hystrix的作用。下面就來看看Hystrix的作用,在服務調用的過程中,爲了防止因爲某些故障而消耗整個服務調用資源,從而導致服務雪崩。所以在服務調用的過程中需要對整個的調用機制有一個熔斷的邏輯。整個時候Hystrix就會排上用場。

  調用方會針對被調用微服務設置調用超時時間,一旦超時就會進入熔斷邏輯,而這個故障指標信息也會返回給Hystrix組件,Hystrix組件會根據熔斷情況判斷被調微服務的故障情況從而打開熔斷器,之後所有針對該微服務的請求就會直接進入熔斷邏輯,直到被調微服務故障恢復,Hystrix斷路器關閉爲止。

  通過上面的描述就形成了如下的這樣一個調用關係圖在這裏插入圖片描述

如何配置

Feign配置說明

  在之前的分享中其實我們知道Feign並不是就簡單的實現了一種HttpClient,它提供了很多HttpClient方式,其中最爲輕量級的就是OKHTTP的配置。下面這種方式是基於Apache HttpClient的方式來實現的。


feign:
  #替換掉JDK默認HttpURLConnection實現的 Http Client
  httpclient:
    enabled: true
  hystrix:
    enabled: true
  client:
    config:
      default:
       #連接超時時間
        connectTimeout: 5000
       #讀取超時時間
        readTimeout: 5000

Hystrix配置說明

  基於整個的Spring Cloud 微服務架構,Hystrix主要的功能是實現微服務之間網絡調用故障的熔斷、過載保護及資源隔離等。所以提供的配置說明也是關於這些內容的。如果單獨使用的話還有其他的配置可以進行自定義。

hystrix:
  propagate:
    request-attribute:
      enabled: true
  command:
    #全局默認配置
    default:
      #線程隔離相關
      execution:
        timeout:
          #是否給方法執行設置超時時間,默認爲true。一般我們不要改。
          enabled: true
        isolation:
          #配置請求隔離的方式,這裏是默認的線程池方式。還有一種信號量的方式semaphore,使用比較少。
          strategy: threadPool
          thread:
            #方式執行的超時時間,默認爲1000毫秒,在實際場景中需要根據情況設置
            timeoutInMilliseconds: 10000
            #發生超時時是否中斷方法的執行,默認值爲true。不要改。
            interruptOnTimeout: true
            #是否在方法執行被取消時中斷方法,默認值爲false。沒有實際意義,默認就好!
            interruptOnCancel: false
  circuitBreaker:   #熔斷器相關配置
    enabled: true   #是否啓動熔斷器,默認爲true,false表示不要引入Hystrix。
    requestVolumeThreshold: 20     #啓用熔斷器功能窗口時間內的最小請求數,假設我們設置的窗口時間爲10秒,
    sleepWindowInMilliseconds: 5000    #所以此配置的作用是指定熔斷器打開後多長時間內允許一次請求嘗試執行,官方默認配置爲5秒。
    errorThresholdPercentage: 50   #窗口時間內超過50%的請求失敗後就會打開熔斷器將後續請求快速失敗掉,默認配置爲50

Ribbon配置說明

  Ribbon在Spring Cloud中對於支持微服之間的通信,其主要功能包括客戶端負載均衡器及用於中間層通信的客戶端。在基於Feign的微服務通信中無論是否開啓Hystrix,Ribbon都是必不可少的,Ribbon的配置參數主要如下:

ribbon:
  eager-load:
    enabled: true
  #說明:同一臺實例的最大自動重試次數,默認爲1次,不包括首次
  MaxAutoRetries: 1
  #說明:要重試的下一個實例的最大數量,默認爲1,不包括第一次被調用的實例
  MaxAutoRetriesNextServer: 1
  #說明:是否所有的操作都重試,默認爲true
  OkToRetryOnAllOperations: true
  #說明:從註冊中心刷新服務器列表信息的時間間隔,默認爲2000毫秒,即2秒
  ServerListRefreshInterval: 2000
  #說明:使用Apache HttpClient連接超時時間,單位爲毫秒
  ConnectTimeout: 3000
  #說明:使用Apache HttpClient讀取的超時時間,單位爲毫秒
  ReadTimeout: 3000

注意 :在Spring Cloud中使用Feign進行微服務調用分爲兩層:Hystrix的調用和Ribbon的調用,Feign自身的配置會被覆蓋。
  而如果開啓了Hystrix,那麼Ribbon的超時時間配置與Hystrix的超時時間配置則存在依賴關係,因爲涉及到Ribbon的重試機制,所以一般情況下都是Ribbon的超時時間小於Hystrix的超時時間,否則會出現以下錯誤:

 o.s.c.n.z.f.r.s.AbstractRibbonCommand - The Hystrix timeout of 10000ms   for the command operation is set lower than the combination of the Ribbon   read and connect timeout, 24000ms.

Ribbon和Hystrix的超時時間配置的關係

  那麼Ribbon和Hystrix的超時時間配置的關係具體是什麼呢?如下:

Hystrix的超時時間=Ribbon的重試次數(包含首次) * (ribbon.ReadTimeout + ribbon.ConnectTimeout)

而Ribbon的重試次數的計算方式爲:

Ribbon重試次數(包含首次)= 1 + ribbon.MaxAutoRetries  +  ribbon.MaxAutoRetriesNextServer  +  (ribbon.MaxAutoRetries * ribbon.MaxAutoRetriesNextServer)

  整個關係可以通過上面那個圖來得到。Ribbon的重試次數=1+(1+1+1)=4,所以Hystrix的超時配置應該>=4*(3000+3000)=24000毫秒。在Ribbon超時但Hystrix沒有超時的情況下,Ribbon便會採取重試機制;而重試期間如果時間超過了Hystrix的超時配置則會立即被熔斷(fallback)。

  如果不配置Ribbon的重試次數,則Ribbon默認會重試一次,加上第一次調用Ribbon,總的的重試次數爲2次,以上述配置參數爲例,Hystrix超時時間配置爲2*6000=12000,

  由於很多情況下,大家一般不會主動配置Ribbon的重試次數,所以做簡單說明,以上超時配置的值只是示範,超時配置有點大不太合適實際的線上場景,可以根據實際情況而定。

如果不啓用Hystrix,Feign的超時時間則是Ribbon的超時時間,Feign自身的配置也會被覆蓋。

總結

  本次分享中最爲重要的就是上面那張圖,其實配置在需要的時候查詢官網或者是百度一下就可以了,實際使用過程中怎麼樣去配置在理解了原理之後就顯得尤爲重要了,上面舉例子一樣,如果不知道圖中展示的過程,怎麼可以瞭解整個的調用配置都是什麼意思。希望本次總結可以讓自己有所提升。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章