在微服務框架中,通過rest api的方式呼叫其他服務是很正常的事情。在spring生態系統中,乙個流行的rest客戶端是feign,這是因為它的聲名式風格和新增不同配置的dry方式。
這篇部落格中,我會討論關於feign客戶端的重試機制。本能的,我們會這樣實現,在try catch和while迴圈中編寫api呼叫語句,並為另乙個api呼叫編寫**,直到滿足條件。這也許能符合我們的目的,但是這會使得我們的**醜陋且無法實現。
理想情況下,所有東西完美執行,且我們不需要重試任何http請求。因此,在feign中,預設是不啟用重試的。然後,完美是不存在的,對於乙個tcp包來說,在網路中有數百萬種方法會死掉。所以,為了啟用重試,你必須把下面的**放在你的客戶端配置中。
@bean
public
retryer
retryer()
你可以在default方法中傳一些引數,比如:間隔時間、最大重試次數等,否則它會以1秒間隔重試5次。
這僅僅會讓feign在碰到io異常的時候重試。這有點道理,對吧? x 應該重試去獲取y,僅僅當y不可達的時候。但這並不是經常發生的。有可能,由於y和z之間的連線斷了,導致y返回5xx的錯誤碼,並且你想在這種情況下重試。要使用它,你必須丟擲retryableexception。為了實現這樣的目的,我們需要實現errordecoder類。**像這樣:
public
class
myerrordecoder
implements
errordecoder
if(response.
status()
==504
)return exception;
}}
feign.client.config.default.error-decoder=com.example.somepackage.myerrordecoder
現在,事情已安排妥當,讓我們看看myerrordecoder
這個類都幹了些什麼。它實現了errordecoder
類並且重寫了它的decode方法,這很明顯。在decode方法內部,首先我們檢查了丟擲的異常是不是已經是retryableexception
。如果已經是retryableexception
,那麼這是feign自己丟擲的異常,並且如果我們返回該異常,feign就會自己進行重試。
如果異常不是retryableexception
,第二段**會執行。在這段**中,我們檢查返回狀態是不是504。如果是,我們手動返回乙個retryableexception
。
我們可以在errordecoder
中乾很多事情。想象乙個場景,你想在任何5xx的錯誤碼時進行重試,無論這是否是你的實際場景。那麼我們應該怎麼做?編寫一堆if/else嘛?不,你不需要,你只需要:
)下面,也是自定義重試機制的乙個方法。你為啥要這麼做?我的場景時,當發生每次重試的時候,我先要列印log。為了定製這個retryer,首先刪除配置中的預設retryer。然後建立乙個模組,像這樣:
@slf4j
@component
@noargsconstructor
public
class
customretryer
implements
retryer
@override
public
void
continueorpropagate
(retryableexception e)
due to {} "
, attempt, e.
getmessage()
);if(attempt++
== retrymaxattempt)
trycatch
(interruptedexception ignored)
}@override
public
retryer
clone()
}
這裡我們的customretryer
重寫了continueorpropagate
和clone
方法,這是feign預設retryer的方法。clone方法中,我們以需要的引數建立了乙個customretryer
,這裡6是最大重試次數,2000l時每次重試的間隔時間。
在continueorpropagate
方法中,你可以定製你的重試機制。記住,為了停止重試並且傳播錯誤資訊,你必須丟擲這個方法收到的retryable異常。否則,它會繼續重試。在這個例子中,我們在嘗試我們設定的最大重試次數之後,丟擲這個異常,否則它會在繼續下一次重試之前,等待間隔時間(引數)。
到目前為止,我們看到的是如何建立乙個自定義的錯誤解碼器和重傳器,以根據我們的需要擴充套件feign的可靠性。如果您以這種方式建立錯誤解碼器和重試器,它將為您新增到專案中的任意數量的feign客戶端工作。但是,想象乙個場景,對於不同的client,你想要不通的重試機制,或者對嶼其他的的client,不進行重試。你要怎麼做?給不通的client,繫結不通的重試器和編碼器是很容易的。像這樣配置就行:
feign.client.config.default..error-decoder=com.example.somepackage.myerrordecoderfeign.client.config.client1.retryer=com.example.somepackage.customretryer
重試快樂!! ribbon的重試機制
客戶端配置 1 新增依賴 org.springframework.retry spring retry 2 新增配置 spring cloud loadbalancer retry enabled true 開啟spring cloud的重試功能 user service ribbon connec...
nginx的重試機制
現在對外服務的 很少只使用乙個服務節點,而是部署多台伺服器,上層通過一定機制保證容錯和負載均衡。nginx就是常用的一種http和反向 伺服器,支援容錯和負載均衡。nginx的重試機制就是容錯的一種。在nginx的配置檔案中,proxy next upstream項定義了什麼情況下進行重試,官網文件...
自定義Feign配置
在springcloud中,feign的預設配置類是feignclientsconfiguration,該類定義了feign預設使用的編碼器 解碼器 所使用的契約 預設支援springmvc註解 等,如果想使用feign自帶的註解 requestline工作,則需要在 feignclient的con...