天天看點

程式員不能不懂的Retry機制 Retry重試機制 Retry重試機制的使用

Retry重試機制

當我們調用一個接口時, 可能由于網絡等原因造成第一次失敗, 再去嘗試就成功了, 這就是重試機制.

重試的解決方案有很多, 比如利用 try-catch-redo簡單重試模式, 通過判斷傳回結果或監聽異常來

判斷是否重試, 具體可以看如下例子:

public void testRetry(){
        boolean result = false;
        try{
            result = load();
            if (!result){
                load(); //一次重試
            }
        }catch (Exception e){
            load(); //一次重試
        }
    }
           

但是這種政策有個問題就是: 正常邏輯和重試邏輯強耦合. 基于這個問題, 我們可以使用 Spring-Retry工具,

該工具把重試操作模闆定制化, 可以設定重試政策和回退政策. 同時 重試執行執行個體保證線程安全.

Retry重試機制的使用

首先在pom.xml中引入所需的依賴:
<dependency>
            <groupId>org.springframework.retry</groupId>
            <artifactId>spring-retry</artifactId>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
        </dependency>
           
添加完依賴後, 需要在入口類Application中添加注解

@EnableRetry

開啟retry重試:
@SpringBootApplication
@EnableRetry
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}
           
然後我們建立個接口RetryService:
/**
 * @Author wuwei
 * @Date 2019/12/8 8:22 下午
 */
public interface RetryService {
    AyMood findByIdRetry(String id);
}
           
接着建立實作類RetryServiceImpl:
/**
 * @Author wuwei
 * @Date 2019/12/8 8:22 下午
 */
@Service
public class RetryServiceImpl implements AyMoodService {
    
    @Override
    @Retryable(value = {BusinessException.class}, maxAttempts = 5,
    backoff = @Backoff(delay = 5000, multiplier = 2))
    public AyMood findByIdRetry(String id) {
        System.out.println("[findByIdRetry]方法重試失敗了!!!");
        throw new BusinessException("retry");
    }

}

           
我們在方法中故意抛出

自定義異常BusinessException

,

關于自定義處理全局異常,請移步: https://blog.csdn.net/dummyo/article/details/103450968

@Retryable

:
  • value屬性表示當出現哪些異常的時候觸發重試
  • maxAttemps: 表示最大重試次數, 預設為3
  • delay表示重試的延遲時間
  • multiplier表示第n次重試是n-1次重試的多少倍.[例子中: 失敗後第一次過5秒後重試, 第二次過10秒, 20秒]
我們寫個測試方法來調用上述方法:
/**
 * @Author wuwei
 * @Date 2019/12/8 10:24 下午
 */
@RestController
@RequestMapping("/start")
public class TestController {
    
    @Autowired
    AyMoodService ayMoodService;
    
    @RequestMapping("/retry")
    public String findByIdRetry(){
        AyMood ayMood = ayMoodService.findByIdRetry("1");
        return "";
    }
}
           
然後在浏覽器中請求這個接口, 會發現控制台一直在進行重試, 5次後就傳回結果.
程式員不能不懂的Retry機制 Retry重試機制 Retry重試機制的使用

Over

如果覺得需要更多技術幹貨, 來我的CSDN 和 GitHub哦

CSDN: https://println.tk/

Github: https://github.com/uweii

繼續閱讀