史上最全: Feign Ribbon Hystrix 三者關系 | 深度解析
瘋狂創客圈 Java 分布式聊天室【 億級流量】實戰系列之 -25【 博客園 總入口 】
前言
瘋狂創客圈(筆者尼恩創建的高並發研習社群)Springcloud 高並發系列文章,將為大家介紹三個版本的 高並發秒殺:
一、版本1 :springcloud + zookeeper 秒殺
二、版本2 :springcloud + redis 分布式鎖秒殺
三、版本3 :springcloud + Nginx + Lua 高性能版本秒殺
以及有關Springcloud 幾篇核心、重要的文章:
二、Springcloud 中 SpringBoot 配置全集 , 收藏版
三、Feign Ribbon Hystrix 三者關系 , 史上最全 深度解析
四、SpringCloud gateway 詳解 , 史上最全
本文,是《Feign Ribbon Hystrix 三者關系 , 史上最全 深度解析》篇,為大家解讀如果Feign Ribbon Hystrix 三者關系,大家可以藏好,一定有用的到時候。
Springcloud 高並發 配置 簡介
在微服務架構的應用中, Feign、Hystrix,Ribbon三者都是必不可少的,可以說已經成為鐵三角。
瘋狂創客圈(筆者尼恩創建的高並發研習社群)中,有不少小伙伴問到尼恩,關於Feign、Hystrix,Ribbon三者之間的關系,以及三者的超時配置。截止目前,全網沒有篇文章介紹清楚的,故,尼恩特寫一篇詳細一點的文章,剖析一下。
Feign介紹
Feign是一款Java語言編寫的HttpClient綁定器,在Spring Cloud微服務中用於實現微服務之間的聲明式調用。Feign 可以定義請求到其他服務的接口,用於微服務間的調用,不用自己再寫http請求,在客戶端實現,調用此接口就像遠程調用其他服務一樣,當請求出錯時可以調用接口的實現類來返回
Feign是一個聲明式的web service客戶端,它使得編寫web service客戶端更為容易。創建接口,為接口添加注解,即可使用Feign。Feign可以使用Feign注解或者JAX-RS注解,還支持熱插拔的編碼器和解碼器。Spring Cloud為Feign添加了Spring MVC的注解支持,並整合了Ribbon和Eureka來為使用Feign時提供負載均衡。
feign源碼的github地址:
https://github.com/OpenFeign/feign
Ribbon介紹
Ribbon 作為負載均衡,在客戶端實現,服務段可以啟動兩個端口不同但servername一樣的服務
Ribbon是Netflix發布的開源項目,主要功能是提供客戶端的軟件負載均衡算法,將Netflix的中間層服務連接在一起。Ribbon客戶端組件提供一系列完善的配置項如連接超時,重試等。簡單的說,就是在配置文件中列出Load Balancer后面所有的機器,Ribbon會自動的幫助你基於某種規則(如簡單輪詢,隨機連接等)去連接這些機器。我們也很容易使用Ribbon實現自定義的負載均衡算法。簡單地說,Ribbon是一個客戶端負載均衡器。
Ribbon工作時分為兩步:第一步先選擇 Eureka Server, 它優先選擇在同一個Zone且負載較少的Server;第二步再根據用戶指定的策略,在從Server取到的服務注冊列表中選擇一個地址。其中Ribbon提供了多種策略,例如輪詢、隨機、根據響應時間加權等。
ribbon源碼的github地址:
https://github.com/Netflix/ribbon
Hystrix介紹
Hystrix作為熔斷流量控制,在客戶端實現,在方法上注解,當請求出錯時可以調用注解中的方法返回
Hystrix熔斷器,容錯管理工具,旨在通過熔斷機制控制服務和第三方庫的節點,從而對延遲和故障提供更強大的容錯能力。在Spring Cloud Hystrix中實現了線程隔離、斷路器等一系列的服務保護功能。它也是基於Netflix的開源框架 Hystrix實現的,該框架目標在於通過控制那些訪問遠程系統、服務和第三方庫的節點,從而對延遲和故障提供更強大的容錯能力。Hystrix具備了服務降級、服務熔斷、線程隔離、請求緩存、請求合並以及服務監控等強大功能。
Hystrix源碼的github地址:
https://github.com/Netflix/hystrix
重點: 三者之間的關系圖
如果微服務項目加上了spring-cloud-starter-netflix-hystrix依賴,那么,feign會通過代理模式, 自動將所有的方法用 hystrix 進行包裝。
在Spring Cloud微服務體系下,微服務之間的互相調用可以通過Feign進行聲明式調用,在這個服務調用過程中Feign會通過Ribbon從服務注冊中心獲取目標微服務的服務器地址列表,之后在網絡請求的過程中Ribbon就會將請求以負載均衡的方式打到微服務的不同實例上,從而實現Spring Cloud微服務架構中最為關鍵的功能即服務發現及客戶端負載均衡調用。
另一方面微服務在互相調用的過程中,為了防止某個微服務的故障消耗掉整個系統所有微服務的連接資源,所以在實施微服務調用的過程中我們會要求在調用方實施針對被調用微服務的熔斷邏輯。而要實現這個邏輯場景在Spring Cloud微服務框架下我們是通過Hystrix這個框架來實現的。
調用方會針對被調用微服務設置調用超時時間,一旦超時就會進入熔斷邏輯,而這個故障指標信息也會返回給Hystrix組件,Hystrix組件會根據熔斷情況判斷被調微服務的故障情況從而打開熔斷器,之后所有針對該微服務的請求就會直接進入熔斷邏輯,直到被調微服務故障恢復,Hystrix斷路器關閉為止。
三者之間的關系圖,大致如下:
Feign典型配置說明
Feign自身可以支持多種HttpClient工具包,例如OkHttp及Apache HttpClient,針對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的超時時間,否則會出現以下錯誤:
2019-10-12 21:56:20,208 111231 [http-nio-8084-exec-2] WARN 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配置為例子,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自身的配置也會被覆蓋。
最后,介紹一下瘋狂創客圈:瘋狂創客圈,一個Java 高並發研習社群 【博客園 總入口 】
瘋狂創客圈,傾力推出:面試必備 + 面試必備 + 面試必備 的基礎原理+實戰 書籍 《Netty Zookeeper Redis 高並發實戰》
瘋狂創客圈 Java 死磕系列
- Java (Netty) 聊天程序【 億級流量】實戰 開源項目實戰
- Netty 源碼、原理、JAVA NIO 原理
- Java 面試題 一網打盡
- 瘋狂創客圈 【 博客園 總入口 】