1. 程式人生 > >Spring學習筆記(十)——Spring Retry篇

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次應該有很大的概率可以成功連線。