1. Springcloud 高併發配置簡介
在微服務架構的應用中, Feign、Hystrix,Ribbon三者都是必不可少的,可以說已經成爲鐵三角。
瘋狂創客圈(筆者尼恩創建的高併發研習社羣)中,有不少小夥伴問到尼恩,關於Feign、Hystrix,Ribbon三者之間的關係,以及三者的超時配置。截止目前,全網沒有篇文章介紹清楚的,故,尼恩特寫一篇詳細一點的文章,剖析一下。
1.1 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時提供負載均衡。
1.2 Ribbon介紹
Ribbon 作爲負載均衡,在客戶端實現,服務段可以啓動兩個端口不同但servername一樣的服務
Ribbon是Netflix發佈的開源項目,主要功能是提供客戶端的軟件負載均衡算法,將Netflix的中間層服務連接在一起。Ribbon客戶端組件提供一系列完善的配置項如連接超時,重試等。簡單的說,就是在配置文件中列出Load Balancer後面所有的機器,Ribbon會自動的幫助你基於某種規則(如簡單輪詢,隨機連接等)去連接這些機器。我們也很容易使用Ribbon實現自定義的負載均衡算法。簡單地說,Ribbon是一個客戶端負載均衡器。
Ribbon工作時分爲兩步:第一步先選擇 Eureka Server, 它優先選擇在同一個Zone且負載較少的Server;第二步再根據用戶指定的策略,在從Server取到的服務註冊列表中選擇一個地址。其中Ribbon提供了多種策略,例如輪詢、隨機、根據響應時間加權等。
1.3 Hystrix介紹
Hystrix作爲熔斷流量控制,在客戶端實現,在方法上註解,當請求出錯時可以調用註解中的方法返回
Hystrix熔斷器,容錯管理工具,旨在通過熔斷機制控制服務和第三方庫的節點,從而對延遲和故障提供更強大的容錯能力。在Spring Cloud Hystrix中實現了線程隔離、斷路器等一系列的服務保護功能。它也是基於Netflix的開源框架 Hystrix實現的,該框架目標在於通過控制那些訪問遠程系統、服務和第三方庫的節點,從而對延遲和故障提供更強大的容錯能力。Hystrix具備了服務降級、服務熔斷、線程隔離、請求緩存、請求合併以及服務監控等強大功能。
2. 重點: 三者之間的關係圖
如果微服務項目加上了spring-cloud-starter-netflix-hystrix依賴,那麼,feign會通過代理模式, 自動將所有的方法用 hystrix 進行包裝。
在Spring Cloud微服務體系下,微服務之間的互相調用可以通過Feign進行聲明式調用,在這個服務調用過程中Feign會通過Ribbon從服務註冊中心獲取目標微服務的服務器地址列表,之後在網絡請求的過程中Ribbon就會將請求以負載均衡的方式打到微服務的不同實例上,從而實現Spring Cloud微服務架構中最爲關鍵的功能即服務發現及客戶端負載均衡調用。
另一方面微服務在互相調用的過程中,爲了防止某個微服務的故障消耗掉整個系統所有微服務的連接資源,所以在實施微服務調用的過程中我們會要求在調用方實施針對被調用微服務的熔斷邏輯。而要實現這個邏輯場景在Spring Cloud微服務框架下我們是通過Hystrix這個框架來實現的。
調用方會針對被調用微服務設置調用超時時間,一旦超時就會進入熔斷邏輯,而這個故障指標信息也會返回給Hystrix組件,Hystrix組件會根據熔斷情況判斷被調微服務的故障情況從而打開熔斷器,之後所有針對該微服務的請求就會直接進入熔斷邏輯,直到被調微服務故障恢復,Hystrix斷路器關閉爲止。
三者之間的關係圖,大致如下:
3. 配置說明
3.1 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
3.2 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
3.3 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.
3.4 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自身的配置也會被覆蓋。