Spring學習筆記(十)——Spring Retry篇
前提
這篇博文是這套Spring學習筆記的第十篇——Spring Retry篇,主要內容包括Spring MVC的基礎知識和應用。如果需要了解有關Spring的綜述資訊或博文的索引資訊,請移步:
《綜述篇》
從問題出發
大家都知道,Java中有一大類異常叫RuntimeException
,執行時異常。可能造成這類這類異常的程式碼可以通過編譯器的語法檢查,在執行的過程中可能會因為網路抖動、記憶體溢位等問題觸發異常。
而我的問題就發生在了網路抖動上。我的工程包含郵件服務,一般情況下可以正常運轉。但是每個月總有那麼一兩次,可能因為網路抖動的原因,程式就會出現郵件伺服器連線超時的異常。原本該定時發出去的郵件,就得手動來發了。
之前看到過有關 Spring Retry的文章,但是存在僥倖心理就沒有學習。隨著使用者的增多,每天要傳送的郵件也多了起來,這樣如果遇到異常,手動傳送那麼多郵件也會特別累。那麼就到了必須學習它的時候了。
Spring Retry
Spring Retry是隸屬於Spring家族的重試框架,它不在Spring的核心包中,需要額外引入。
就上述的幾種Runtime Exception
,記憶體溢位這類的異常是不適合用它來解決的,因為你的異常可能是因為邏輯異常造成的,錯了就是錯了,重試多少次結果都一樣。但是網路抖動這類的異常不同,只要程式碼邏輯無誤,除非對面的伺服器徹底奔潰了,我重試一遍、兩遍連不上,重試十遍、二十遍總是能連上的。
開始實現
首先從Maven中央倉庫找到POM資訊:
<!-- https://mvnrepository.com/artifact/org.springframework.retry/spring-retry -->
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>1.2.2.RELEASE</version>
</ dependency>
加入到pom.xml
檔案的<dependencies>
標籤中。
接下來看程式碼,我的程式碼中會觸發連線超時異常的程式碼就是這幾行:
public Session getSession(Properties properties) {
return Session.getInstance(properties);
}
在獲取會話的過程中,因為網路波動,就會出現連線超時的情況。
實現Retry需要以下的幾個步驟:
①給函式所在的類冠上@EnableRetry
註解,啟用重試
@EnableRetry(proxyTargetClass = true)
在前面的博文中我們說過,proxyTargetClass設定為false
時使用基於介面的代理,設定為true
時,使用基於類的代理(需要引用cglib
包)。
②給需要重試的函式冠上@Retryable
註解
@Retryable(value = MailConnectException.class, maxAttempts = 60, backoff = @Backoff)
其中:
1)value
指示的是目標異常,即遇到該異常就重試;
2)maxAttempts
表示最大嘗試次數;
3)backoff
表示退避演算法,預設使用@Backoff
註解,即延時1000ms進行下一次重試。
③新增兜底方法
兜底方法即達到最大重試次數仍失敗後的處理方法,他需要:
1)被冠以@Recover
註解;
2)使用上述被重試的函式指定的異常作為入參,如上述的MailConnectException
郵件連線異常。
@Recover
public void recover(MailConnectException mce) {
logger.error("Mail Connection Still Failing After 60 Times of Attempts.", mce);
}
我這裡做的是向log檔案中輸出log資訊Mail Connection Still Failing After 60 Times of Attempts.
,即嘗試60次之後,連線仍然失敗了。
後記
Retry雖然不能完全解決網路抖動的問題,但是可以大幅的提高工程的魯棒性,相信除非對面的伺服器徹底崩潰了,或者網路徹底中斷了,重試個60次應該有很大的概率可以成功連線。