spring
spring-retry 重試機制
2019/10/14 10:23:48
2
3646
前言
在實作中,重試處理是一個非常常見的情況,例如:傳送訊息失敗,呼叫遠端服務失敗等等...,這些錯誤可能是因為網路不穩造成的,等待過後,在重試就能成功。通常會用try/catch,while迴圈來進行重試處理的控制,然而spring-retry卻可以使用@annotation來方便的實現重試處理的功能。
如何使用spring-retry?
- pom.xml新增spring-retry
<!-- https://mvnrepository.com/artifact/org.springframework.retry/spring-retry -->
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>1.2.4.RELEASE</version>
</dependency>
- build.gradle新增spring-retry
// https://mvnrepository.com/artifact/org.springframework.retry/spring-retry
compile group: 'org.springframework.retry', name: 'spring-retry', version: '1.2.4.RELEASE'
Application上添加@EnableRetry
@SpringBootApplication
@EnableRetry
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
在需要重試方法上添加@Retryable
以下針對常用的值進行介紹
- value:指定失敗重試的Exception類型
- include:和value效果一樣,當exclude為空時,所有Exceoption都會重試,預設空
- exclude:指定Exceoption不重試,當include為空時,所有Exceoption都會重試,預設空
- maxAttempts:指定重試的次數,預設3
- backoff:重試補償機制,預設沒有
@Backoff
delay:指定延遲後重試
multiplier:指定延遲的倍数,例如:delay=3000l, multiplier=2,第一次重試為3秒,第二次為6秒,第三次為12秒
@Retryable(value = DemoException.class, maxAttempts = 4, backoff = @Backoff(delay = 3000l))
public void testSpringRetry() {
logger.info("測試Spring Retry重試---------------------------- {}", LocalTime.now());
throw new DemoException();
}
在重試回調的方法上添加@Recover
重試的次數達到所指定的次數時,就會執行此方法
注意:發生Exception和參數的Exception類型需要一致才會回調
@Recover
private void testRecover(DemoException e){
logger.error("測試Recover...");
}
添加測試spring-retry
@PostMapping(path = "/testSpringRetry")
public String testSpringRetry() {
demoService.testSpringRetry();
return "";
}
@Retryable執行結果
- 執行結果可以發現,方法重試了四次,而且每隔三秒重試一次
-
重試四次後,執行@Recover的方法
與re-try-catch做比較
public void testTryCatchRedo() throws Exception {
int count = 0;
int maxAttempts = 4;
int delaySec = 3;
while (true) {
try {
logger.info("測試try-catch-redo重試---------------------------- {}", LocalTime.now());
throw new DemoException();
} catch (DemoException e) {
Thread.sleep(delaySec * 1000);
if (++count == maxAttempts)
throw e;
}
}
}
添加測試re-try-catch
@PostMapping(path = "/testSpringRetry")
public String testSpringRetry() {
demoService.testSpringRetry();
return "";
}
re-try-catch執行結果
- 與上面的@Retryable執行結果一樣
- 方法重試了四次,而且每隔三秒重試一次
結語
透過spring-retry就能簡單地透過設定來進行重試機制,而不在需要使用較為繁瑣的寫法來控制重試機制。