Spring retry基本使用


Spring retry基本使用

背景介紹

在實際工作過程中,重試是一個經常使用的手段。比如MQ發送消息失敗,會采取重試手段,比如工程中使用RPC請求外部服務,可能因為網絡
波動出現超時而采取重試手段......可以看見重試操作是非常常見的一種處理問題,系統設計的手段

而在之前我們項目中處理重拾操作依賴MQ自身的重試機制,但是這種機制不是很靈活,如果某些功能沒有使用MQ的話,那么就不是那么方便了,而本文介紹的
Spring-Retry卻能夠以一種很優雅的方式解決這種問題,當然目前版本的Spring-retry還不是完美的,還是有待改進的.不過已經很不錯了.

基本使用

  • 例子1

      @Configuration
      @EnableRetry
      public class Application {
      
          @Bean
          public Service service() {
              return new Service();
          }
      
      }
      
      @Service
      class Service {
          @Retryable(RemoteAccessException.class)
          public void service() {
              // ... do something
          }
          @Recover
          public void recover(RemoteAccessException e) {
             // ... panic
          }
      }
    
  • 例子2

     @org.springframework.stereotype.Service
     public class Service1 {
     
         @Retryable(value = {RemoteAccessException.class, RuntimeException.class},
                 maxAttempts = 2,
                 backoff = @Backoff(value = 2000))
         public void service() {
             System.out.println("do some things");
             // this exception will just trigger recover1, do not trigger recover3
             throw new RemoteAccessException("remote access exception");
             // this exception will just trigger recover2
     //        throw new RuntimeException("runtime exception");
     
     //        System.out.println("do another things");
         }
     
         // 如果使用注解的話,這個recover貌似只能寫在本類中,我測試了如果將recover方法寫在
         // recoverService中,好像找不到
     
         @Recover
         public void recover1(RemoteAccessException e) {
             System.out.println(e.getMessage());
             System.out.println("do recover operation1");
         }
     
         @Recover
         public void recover2(RuntimeException e) {
             System.out.println(e.getMessage());
             System.out.println("do recover operation2");
         }
     
         @Recover
         public void recover3(RemoteAccessException e) {
             System.out.println(e.getMessage());
             System.out.println("do recover operation3");
         }
     
     }
    
  • 例子3

     @Service
     public class Service2 {
     
         public void test(){
             final RetryTemplate retryTemplate = new RetryTemplate();
             final SimpleRetryPolicy policy = new SimpleRetryPolicy(3, Collections.<Class<? extends Throwable>, Boolean>
                     singletonMap(Exception.class, true));
             FixedBackOffPolicy fixedBackOffPolicy = new FixedBackOffPolicy();
             fixedBackOffPolicy.setBackOffPeriod(100);
             retryTemplate.setRetryPolicy(policy);
             retryTemplate.setBackOffPolicy(fixedBackOffPolicy);
             final RetryCallback<Object, Exception> retryCallback = new RetryCallback<Object, Exception>() {
                 public Object doWithRetry(RetryContext context) throws Exception {
                     System.out.println("do some thing");
                     //設置context一些屬性,給RecoveryCallback傳遞一些屬性
                     context.setAttribute("key1", "value1");
                     System.out.println(context.getRetryCount());
                     throw new Exception("exception");
     //                return null;
                 }
             };
     
             // 如果RetryCallback執行出現指定異常, 並且超過最大重試次數依舊出現指定異常的話,就執行RecoveryCallback動作
             final RecoveryCallback<Object> recoveryCallback = new RecoveryCallback<Object>() {
                 public Object recover(RetryContext context) throws Exception {
                     System.out.println("do recory operation");
                     System.out.println(context.getAttribute("key1"));
                     return null;
                 }
             };
     
             try {
                 final Object execute = retryTemplate.execute(retryCallback, recoveryCallback);
             } catch (Exception e) {
                 e.printStackTrace();
             }
         }
     }
    

參考資料


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM