springboot整合spring-retry的實現示例
1、背景
本系統呼叫外圍系統介面(http+json),但是發現有時外圍系統服務不太穩定,有時候會出現返回一串xml或者gateway bad的資訊,導致呼叫失敗,基於這一原因,採用基於springboot,整合spring-retry的重試機制到系統工程中,demo已經放到github上。
2、解決方案
簡要說明:demo工程基於springboot,為了方便驗證,採用swagger進行測試驗證。
2.1 pom檔案
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.5.0</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>http://www.cppcns.comcom.laowang</groupId> <artifactId>springretry</artifactId> <version>0.0.1-SNAPSHOT</version> <name>springretry</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--retry--> <dependency> <groupId>org.springframework.retry</groupId>程式設計客棧<artifactId>spring-retry</artifactId> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> </dependency> <!--swagger--> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.7.0</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.7.0</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build> </project>
重點說明:aop的gav必須有,否則會跑不起來。
<!--retry--> <dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> </dependency>
2.2 applicat啟動類
package com.laowang.springretry; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.retry.annotation.EnableRetry; import springfox.documentation.swagger2.annotations.EnableSwagger2; @EnableRetry @EnableSwagger2 @SpringBootApplication public class SpringretryApplication { public static void main(String[] args) { SpringApplication.run(SpringretryApplication.class,args); } }
說明:兩個標籤而已
@EnableRetry @EnableSwagger2
2.3 controller類
/** * @description: TODO * @author Administrator * @date 2021/6/2 14:55 * @version 1.0 */ package com.laowang.springretry.controller; import com.laowang.springretry.service.RetryService; import io.swagger.annotations.Api; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @Api("重試測試類") @RestController public class RetryController { @Autowired RetryService retryService; @GetMapping("/testRetry") public String testRetry(int code) throws Exception { int result = retryService.retryTest(code); return "result:" + result; } }
2.4 service測試類(重點)
/** * @description: TODO * @author Administrator * @date 2021/6/2 12:23 * @version 1.0 */ package com.laowang.springretry.serviFsAYKILnPwce; import org.springframework.retry.annotation.Backoff; import org.springframework.retry.annotation.Recover; import org.springframework.retry.annotation.Retryable; import org.springframework.stereotype.Service; import java.time.LocalTime; @Service public class RetryServiceImpl implements RetryService { @Override @Retryable(value = Exception.class,maxAttempts = 3,backoff = @Backoff(delay = 2000,multiplier = 1.5)) public int retryTest(int code) throws Exception { System.out.priFsAYKILnPwntln("retryTest被呼叫,時間:" + LocalTime.now()); if (code == 0) { throw new Exception("異常丟擲!"); } System.out.println("retryTest被呼叫,情況對頭了!"); return 200; } @Recover public int recover(Exception e) { System.out.println("回撥方法執行,可以記錄日誌到資料庫!!!!"); www.cppcns.com //記日誌到資料庫 或者呼叫其餘的方法 return 400; } }
**說明:**三個標籤
@Retryable註解
被註解的方法發生異常時會重試
value:指定發生的異常進行重試
include:和value一樣,預設空,當exclude也為空時,所有異常都重試
exclude:指定異常不重試,預設空,當include也為空時,所有異常都重試
maxAttemps:重試次數,預設3
backoff:重試補償機制,預設沒有
@Backoff註解說明
delay:指定延遲後重試
multiplier:指定延遲的倍數,比如delay=2000,multiplier=1.5時,第二次重試與第一次執行間隔:2秒;第三次重試與第二次重試間隔:3秒;第四次重試與第三次重試間隔:4.5秒。。。
@Recover
當重試到達指定次數時,被註解的方法將被回撥,可以在該方法中進行日誌處理。需要注意的是發生的異常和入參型別一致時才會回撥
2.5 專案啟動
執行執行application,啟動成功,預設埠號:8080
2.6 使用swagger進行驗證
(1)swagger訪問地址:
http://localhost:8080/swagger-ui.html
(2)先驗證成功返回
先測試正常呼叫試試,code=1
呼叫返回:
(3)重試機制:code=0(重點)
為了更好的說明問題,引數配置增大一些:
@Retryable(value = Exception.class,maxAttempts = 5,multiplier = 2))
執行效果
說明:
從執行效果看,總共執行5次,第二次跟第一次之間是2秒;第三次跟第二次之間是2*2=4秒;第四次與第三次之間是:2 乘以2乘以2=8秒,第五次與第四次之間是:2 乘以2乘以2乘以2=16秒,符合預期。
執行完成後,進入 @Recover標籤內容,可以進行日誌記錄,以便後續定位問題。
github專案地址:https://github.com/ruanjianlaowang/springretry
到此這篇關於springboot整合spring-retry的實現示例的文章就介紹到這了,更多相關springboot整合spring-retry內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!