先看下ribbon的配置和hystrix的超時配置
ribbon:
MaxAutoRetries: 1 #最大重試次數,當Eureka中可以找到服務,但是服務連不上時將會重試
MaxAutoRetriesNextServer: 1 #切換實例的重試次數
OkToRetryOnAllOperations: true # 對所有的操作請求都進行重試,如果是get則可以,如果是post,put等操作沒有實現冪等的情況下是很危險的
ConnectTimeout: 250 #請求連接的超時時間
ReadTimeout: 1000 #請求處理的超時時間
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 4500
#如果配置ribbon的重試,hystrix的超時時間要大於ribbon的超時時間,ribbon纔會重試
#hystrix的超時時間
看完之後,我有3個問題請讀者思考下:
1、ribbon會發送幾次請求?
2、hystrix的超時時間該配置多少?
3、OkToRetryOnAllOperations, 爲什麼我要配置爲true?
答案如下:
1、ribbon會發送幾次請求?
答:4次。
2、hystrix的超時時間該配置多少?
答:>4000毫秒
3、OkToRetryOnAllOperations, 爲什麼我要配置爲true?
答:因爲我請求feign接口爲post,配置爲false時ribbon不會重試。
可能有的人看完跟自己想的答案不是一致的,看完下面你就明白了,最主要的是自己要實驗下。一般情況下 都是 ribbon 的超時時間(<)hystrix的超時時間(因爲涉及到ribbon的重試機制)因爲ribbon的重試機制和Feign的重試機制有衝突,所以源碼中默認關閉Feign的重試機制。
要開啓Feign的重試機制如下:(Feign默認重試五次 源碼中有)
@Bean
Retryer feignRetryer() {
return new Retryer.Default();
}
ribbon:
MaxAutoRetries: 1 #最大重試次數,當Eureka中可以找到服務,但是服務連不上時將會重試
MaxAutoRetriesNextServer: 1 #切換實例的重試次數
OkToRetryOnAllOperations: true # 對所有的操作請求都進行重試,如果是get則可以,如果是post,put等操作沒有實現冪等的情況下是很危險的
ConnectTimeout: 250 #請求連接的超時時間
ReadTimeout: 1000 #請求處理的超時時間
根據上面的參數計算重試的次數:
MaxAutoRetries+MaxAutoRetriesNextServer+(MaxAutoRetries *MaxAutoRetriesNextServer)
即重試3次 則一共產生4次調用 。
如果在重試期間,時間超過了hystrix的超時時間,便會立即執行熔斷,fallback。所以要根據上面配置的參數計算hystrix的超時時間,使得在重試期間不能達到hystrix的超時時間,不然重試機制就會沒有意義
先說明一下,不要用下面這種公式來配置hystrix的超時時間,不要,不要,重要的事情說3次:
hystrix超時時間的計算: (1 + MaxAutoRetries + MaxAutoRetriesNextServer) * ReadTimeout 即按照以上的配置 hystrix的超時時間應該配置爲 (1+1+1)*3=9秒
正確的計算公式:
ReadTimeout+(MaxAutoRetries * ReadTimeout),如果配置的有:MaxAutoRetriesNextServer這個屬性,看下面例子:
ribbon:
MaxAutoRetries: 1 #最大重試次數,當Eureka中可以找到服務,但是服務連不上時將會重試
MaxAutoRetriesNextServer: 1 #切換實例的重試次數
OkToRetryOnAllOperations: true # 對所有的操作請求都進行重試,如果是get則可以,如果是post,put等操作沒有實現冪等的情況下是很危險的
ConnectTimeout: 250 #請求連接的超時時間
ReadTimeout: 1000 #請求處理的超時時間
這個hystrix的超時時間怎麼配置:
ReadTimeout+(MaxAutoRetries * ReadTimeout)+ ReadTimeout+(MaxAutoRetries * ReadTimeout)= 4000ms
那麼hystrix的超時時間爲:>4000ms
如果MaxAutoRetriesNextServer=1,就加1個:
ReadTimeout+(MaxAutoRetries * ReadTimeout)+ ReadTimeout+(MaxAutoRetries * ReadTimeout)= 4000ms
如果MaxAutoRetriesNextServer=2,就加2個:
ReadTimeout+(MaxAutoRetries * ReadTimeout)+ ReadTimeout+(MaxAutoRetries * ReadTimeout)+ ReadTimeout+(MaxAutoRetries * ReadTimeout)= 6000ms
先算出所有ribbon的超時時間+重試時間的總和,那麼hystrix的超時時間大於總和,就可以保證ribbon在重試過程中不會被hystrix熔斷。
當ribbon超時後且hystrix沒有超時,便會採取重試機制。當OkToRetryOnAllOperations設置爲false時,只會對get請求進行重試。如果設置爲true,便會對所有的請求進行重試,如果是put或post等寫操作,如果服務器接口沒做冪等性,會產生不好的結果,所以OkToRetryOnAllOperations慎用。如果不配置ribbon的重試次數,默認會重試一次 。
注意:
默認情況下,GET方式請求無論是連接異常還是讀取異常,都會進行重試
非GET方式請求,只有連接異常時,纔會進行重試
如果上述配置還沒有成功重試,加上如下配置:(開啓客戶端負載均衡,高版本的默認開啓)
spring:
cloud:
loadbalancer:
retry:
enabled: true