Feign、ribbon設置超時時間和重試機制
前言
我們在微服務調用服務的時候,會使用feign和ribbon,比如有一個實例發生了故障而該情況還沒有被服務治理機制及時的發現和摘除,這時候客戶端訪問該節點的時候自然會失敗。
所以,為了構建更為健壯的應用系統,我們希望當請求失敗的時候能夠有一定策略的重試機制,而不是直接返回失敗。
先看一個配置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
#預加載配置,默認為懶加載 ribbon: eager-load: enabled: true clients: zoo-plus-email zoo-plus-email: ribbon: # 代表Ribbon使用的負載均衡策略 NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 每臺服務器最多重試次數,但是首次調用不包括在內 MaxAutoRetries: 1 # 最多重試多少臺服務器 MaxAutoRetriesNextServer: 1 # 無論是請求超時或者socket read timeout都進行重試 OkToRetryOnAllOperations: true ReadTimeout: 3000 ConnectTimeout: 3000 hystrix: command: default : execution: isolation: thread: timeoutInMilliseconds: 4000 |
一般情況下 都是 ribbon 的超時時間(<)hystrix的超時時間(因為涉及到ribbon的重試機制)
Feign重試:
因為ribbon的重試機制和Feign的重試機制有沖突,所以源碼中默認關閉Feign的重試機制,具體看一看源碼
要開啟Feign的重試機制如下:(Feign默認重試五次 源碼中有)
1
2
3
4
|
@Bean Retryer feignRetryer() { return new Retryer.Default(); } |
ribbon的重試機制 :
1
2
3
4
5
6
|
ribbon: ReadTimeout: 3000 ConnectTimeout: 3000 MaxAutoRetries: 1 #同一臺實例最大重試次數,不包括首次調用 MaxAutoRetriesNextServer: 1 #重試負載均衡其他的實例最大重試次數,不包括首次調用 OkToRetryOnAllOperations: false #是否所有操作都重試 |
計算重試的次數:
1
|
MaxAutoRetries+MaxAutoRetriesNextServer+(MaxAutoRetries *MaxAutoRetriesNextServer) |
即重試3次 加上第一次調用一共產生4次調用 。
注意:如果在重試期間,時間超過了hystrix的超時時間,便會立即執行熔斷,fallback。所以要根據上面配置的參數計算hystrix的超時時間,使得在重試期間不能達到hystrix的超時時間,不然重試機制就會沒有意義 。
hystrix超時時間的計算:
1
|
( 1 + MaxAutoRetries + MaxAutoRetriesNextServer) * ReadTimeout |
即按照以上的配置 hystrix的超時時間應該配置為 (1+1+1)*3=9秒
當ribbon超時后且hystrix沒有超時,便會采取重試機制。當OkToRetryOnAllOperations設置為false時,只會對get請求進行重試。如果設置為true,便會對所有的請求進行重試,如果是put或post等寫操作,如果服務器接口沒做冪等性,會產生不好的結果,所以OkToRetryOnAllOperations慎用。
如果不配置ribbon的重試次數,默認會重試一次
注意: 默認情況下,GET方式請求無論是連接異常還是讀取異常,都會進行重試 ,非GET方式請求,只有連接異常時,才會進行重試
Feign、Ribbon、Hystrix三者超時時間配置
Feign設置
1
2
3
4
5
6
7
8
9
10
11
12
13
|
feign: hystrix: enabled: true client: config: # 全局配置 default : connectTimeout: 5000 readTimeout: 5000 # 實例配置,feignName即 @feignclient 中的value,也就是服務名 feignName: connectTimeout: 5000 readTimeout: 5000 |
Ribbon設置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
# 全局配置 ribbon: # 單個服務最大重試次數,不包含對單個服務的第一次請求,默認 0 MaxAutoRetries: 3 # 服務切換次數,不包含最初的服務,如果服務注冊列表小于 nextServer count 那么會循環請求 A > B > A,默認 1 MaxAutoRetriesNextServer: 2 #是否所有操作都進行重試,默認只重試get請求,如果修改為 true ,則需注意post\put等接口冪等性 OkToRetryOnAllOperations: false #連接超時時間,單位為毫秒,默認 2 秒 ConnectTimeout: 3000 #讀取的超時時間,單位為毫秒,默認 5 秒 ReadTimeout: 3000 # 實例配置 clientName: ribbon: MaxAutoRetries: 5 MaxAutoRetriesNextServer: 3 OkToRetryOnAllOperations: false ConnectTimeout: 3000 ReadTimeout: 3000 |
Hystrix設置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
hystrix: command: #全局默認配置 default : #線程隔離相關 execution: timeout: #是否給方法執行設置超時時間,默認為 true 。一般我們不要改。 enabled: true isolation: #配置請求隔離的方式,這里是默認的線程池方式。還有一種信號量的方式semaphore。 strategy: THREAD thread: #方式執行的超時時間,默認為 1000 毫秒,在實際場景中需要根據情況設置 timeoutInMilliseconds: 10000 # 實例配置 HystrixCommandKey: execution: timeout: enabled: true isolation: strategy: THREAD thread: timeoutInMilliseconds: 10000 |
Feign重試和Ribbon重試
feign自身重試目前只有一個簡單的實現Retryer.Default,包含三個屬性:
-
maxAttempts
:重試次數,包含第一次 -
period
:重試初始間隔時間,單位毫秒 -
maxPeriod
:重試最大間隔時間,單位毫秒
ribbon重試包含兩個屬性:MaxAutoRetries和MaxAutoRetriesNextServer
總重試次數= 訪問的服務器數 * 單臺服務器最大重試次數
即:(1+MaxAutoRetriesNextServer)*(1+MaxAutoRetries )
按上面實例的配置,則總重試次數 =(1+2)*(1+3) = 12
超時時間設置
feign和ribbon的超時時間只會有一個生效,規則:如果沒有設置過feign超時,也就是等于默認值的時候,就會讀取ribbon的配置,使用ribbon的超時時間和重試設置。否則使用feign自身的設置。兩者是二選一的,且feign優先。
以Ribbon的時間生效為例,Hystrix的超時時間需大于Ribbon重試總和時間,否則重試將失效,即: Hystrix超時時間 > (Ribbon超時時間總和)*重試次數
按上面的例子,hystrix超時時間>12*(3000+3000)
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持服務器之家。
原文鏈接:https://blog.csdn.net/qq_36850813/article/details/102816423