Spring retry基本使用

Spring retry基本使用

背景介紹

在實際工做過程當中,重試是一個常常使用的手段。好比MQ發送消息失敗,會採起重試手段,好比工程中使用RPC請求外部服務,可能由於網絡
波動出現超時而採起重試手段......能夠看見重試操做是很是常見的一種處理問題,系統設計的手段html

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

基本使用

  • 例子1git

    @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
          }
      }
  • 例子2github

    @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");
         }
    
     }
  • 例子3spring

    @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();
             }
         }
     }

參考資料

相關文章
相關標籤/搜索