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