springboot(十四)使用spring retry

来源:互联网 发布:apache的ftpclient 编辑:程序博客网 时间:2024/06/01 12:23
转载:http://blog.csdn.net/u011493599/article/details/70171977

在调用第三方接口或者使用mq时,会出现网络抖动,连接超时等网络异常,所以需要重试。

1、引入jar包

[java] view plain copy
print?
  1. <dependency>  
  2.             <groupId>org.springframework.retry</groupId>  
  3.             <artifactId>spring-retry</artifactId>  
  4.         </dependency>  
  5.         <dependency>  
  6.             <groupId>org.aspectj</groupId>  
  7.             <artifactId>aspectjweaver</artifactId>  
  8.         </dependency>  
<dependency>            <groupId>org.springframework.retry</groupId>            <artifactId>spring-retry</artifactId>        </dependency>        <dependency>            <groupId>org.aspectj</groupId>            <artifactId>aspectjweaver</artifactId>        </dependency>

2、模拟网络异常,创建一个异常

 

[java] view plain copy
print?
  1. package com.demo.exception;  
  2.   
  3. import lombok.Builder;  
  4. import lombok.Getter;  
  5.   
  6. /** 
  7.  * Created by huguoju on 2017/4/13. 
  8.  */  
  9. @Builder  
  10. @Getter  
  11. public class RetryException extends RuntimeException {  
  12.     private String code;  
  13.     private String message;  
  14. }  
package com.demo.exception;import lombok.Builder;import lombok.Getter;/** * Created by huguoju on 2017/4/13. */@Builder@Getterpublic class RetryException extends RuntimeException {    private String code;    private String message;}

3、在Application上添加@EnableRetry开启Retry服务

[java] view plain copy
print?
  1. @EnableRetry  
  2. public class SpringbootApplication {  
@EnableRetrypublic class SpringbootApplication {

4、在service模拟访问异常,抛出异常

[java] view plain copy
print?
  1. package com.demo.service.impl;  
  2.   
  3. import com.demo.exception.RetryException;  
  4. import com.demo.service.RetryService;  
  5. import lombok.extern.slf4j.Slf4j;  
  6. import org.springframework.retry.annotation.Backoff;  
  7. import org.springframework.retry.annotation.Recover;  
  8. import org.springframework.retry.annotation.Retryable;  
  9. import org.springframework.stereotype.Service;  
  10.   
  11. /** 
  12.  * Created by huguoju on 2017/4/13. 
  13.  */  
  14. @Service(“retryService”)  
  15. @Slf4j  
  16. public class RetryServiceImpl implements RetryService {  
  17.     int i=1;  
  18.     @Override  
  19.     @Retryable(value = {RuntimeException.class},maxAttempts = 4,backoff = @Backoff(delay = 1000l,multiplier = 1))  
  20.     public String retry() {  
  21.         log.info(”测试retry”);  
  22.         i++;//生产环境此处应该为调用第三方接口,判断接口返回code  
  23.         if(i==3){  
  24.             return i+“”;  
  25.         }  
  26.         RetryException retryException=RetryException.builder().code(”9999”).message(“连接超时”).build();  
  27.         throw retryException;  
  28.     }  
  29.   
  30.    
  31.     @Recover  
  32.     public String recover(RetryException e){  
  33.         log.info(e.getMessage());  
  34.         return “6”;  
  35.     }  
  36. }  
package com.demo.service.impl;import com.demo.exception.RetryException;import com.demo.service.RetryService;import lombok.extern.slf4j.Slf4j;import org.springframework.retry.annotation.Backoff;import org.springframework.retry.annotation.Recover;import org.springframework.retry.annotation.Retryable;import org.springframework.stereotype.Service;/** * Created by huguoju on 2017/4/13. */@Service("retryService")@Slf4jpublic class RetryServiceImpl implements RetryService {    int i=1;    @Override    @Retryable(value = {RuntimeException.class},maxAttempts = 4,backoff = @Backoff(delay = 1000l,multiplier = 1))    public String retry() {        log.info("测试retry");        i++;//生产环境此处应该为调用第三方接口,判断接口返回code        if(i==3){            return i+"";        }        RetryException retryException=RetryException.builder().code("9999").message("连接超时").build();        throw retryException;    }    @Recover    public String recover(RetryException e){        log.info(e.getMessage());        return "6";    }}

说明:

@Retryable:标注此注解的方法在发生异常时会进行重试
参数说明:value:抛出指定异常才会重试
          include:和value一样,默认为空,当exclude也为空时,默认所以异常
          exclude:指定不处理的异常
          maxAttempts:最大重试次数,默认3次
          backoff:重试等待策略,默认使用@Backoff,@Backoff的value默认为1000L,multiplier(指定延迟倍数)
                   默认为0,表示固定暂停1秒后进行重试,如果把multiplier设置为2,则第一次重试为1秒,第二次为
                   2秒,第三次为4秒
@Recover:用于@Retryable重试失败后处理方法,此方法里的异常一定要是@Retryable方法里抛出的异常,否则不会调用
          这个方法
5、在其他service里调用上面的service抛出异常
   
[cpp] view plain copy
print?
  1. @Override  
  2.     public Map testRetry() {  
  3.         Map map= Maps.newHashMap();  
  4.         String s=retryService.retry();  
  5.         if (s.equals(“3”)){  
  6.             log.info(”成功啦啦啦啦啦啦啦啦”);  
  7.         }else {  
  8.             log.info(”失败了”);  
  9.         }  
  10.         map.put(”result”,s);  
  11.         return map;  
  12.     }  
@Override    public Map testRetry() {        Map map= Maps.newHashMap();        String s=retryService.retry();        if (s.equals("3")){            log.info("成功啦啦啦啦啦啦啦啦");        }else {            log.info("失败了");        }        map.put("result",s);        return map;    }

6、定义测试controller
[java] view plain copy
print?
  1. package com.demo.controller;  
  2.   
  3. import com.demo.service.RetryService;  
  4. import com.demo.service.TestService;  
  5. import com.google.common.collect.Maps;  
  6. import io.swagger.annotations.Api;  
  7. import org.springframework.beans.factory.annotation.Autowired;  
  8. import org.springframework.http.MediaType;  
  9. import org.springframework.web.bind.annotation.RequestMapping;  
  10. import org.springframework.web.bind.annotation.RequestMethod;  
  11. import org.springframework.web.bind.annotation.RestController;  
  12.   
  13. import java.util.Map;  
  14.   
  15. /** 
  16.  * Created by huguoju on 2017/4/13. 
  17.  */  
  18. @RestController  
  19. @RequestMapping(“retry”)  
  20. @Api(value = “重试机制”,tags = “重试机制”)  
  21. public class RetryController {  
  22.     @Autowired  
  23.     public TestService testService;  
  24.     @RequestMapping(value = “testRetry”,method = {RequestMethod.POST,RequestMethod.GET},produces = MediaType.APPLICATION_JSON_UTF8_VALUE)  
  25.     public Map testRetry(){  
  26.         Map map=Maps.newHashMap();  
  27.         try {  
  28.             map= testService.testRetry();  
  29.             return map;  
  30.         }catch (Exception e){  
  31.             e.printStackTrace();  
  32.             return map;  
  33.         }  
  34.     }  
  35. }  
package com.demo.controller;import com.demo.service.RetryService;import com.demo.service.TestService;import com.google.common.collect.Maps;import io.swagger.annotations.Api;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.http.MediaType;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RestController;import java.util.Map;/** * Created by huguoju on 2017/4/13. */@RestController@RequestMapping("retry")@Api(value = "重试机制",tags = "重试机制")public class RetryController {    @Autowired    public TestService testService;    @RequestMapping(value = "testRetry",method = {RequestMethod.POST,RequestMethod.GET},produces = MediaType.APPLICATION_JSON_UTF8_VALUE)    public Map testRetry(){        Map map=Maps.newHashMap();        try {            map= testService.testRetry();            return map;        }catch (Exception e){            e.printStackTrace();            return map;        }    }}

访问controller,看日志输出
[java] view plain copy
print?
  1. 15:21:30 WARN  [qtp1129243682-21]  com.atomikos.icatch.imp.TransactionServiceImp - Attempt to create a transaction with a timeout that exceeds com.atomikos.icatch.max_timeout - truncating to: 300000  
  2. 15:21:30 INFO  [qtp1129243682-21]  com.atomikos.icatch.imp.BaseTransactionManager - createCompositeTransaction ( 10000000 ): created new ROOT transaction with id 10.3.5.31.tm0000100002  
  3. 15:21:30 INFO  [qtp1129243682-21]  com.demo.service.impl.RetryServiceImpl - 测试retry  
  4. 15:21:31 INFO  [qtp1129243682-21]  com.demo.service.impl.RetryServiceImpl - 测试retry  
  5. 15:21:31 INFO  [qtp1129243682-21]  com.demo.service.impl.TestServiceImpl - 成功啦啦啦啦啦啦啦啦  
  6. 15:21:31 INFO  [qtp1129243682-21]  com.atomikos.icatch.imp.CompositeTransactionImp - commit() done (by application) of transaction 10.3.5.31.tm0000100002  
15:21:30 WARN  [qtp1129243682-21]  com.atomikos.icatch.imp.TransactionServiceImp - Attempt to create a transaction with a timeout that exceeds com.atomikos.icatch.max_timeout - truncating to: 30000015:21:30 INFO  [qtp1129243682-21]  com.atomikos.icatch.imp.BaseTransactionManager - createCompositeTransaction ( 10000000 ): created new ROOT transaction with id 10.3.5.31.tm000010000215:21:30 INFO  [qtp1129243682-21]  com.demo.service.impl.RetryServiceImpl - 测试retry15:21:31 INFO  [qtp1129243682-21]  com.demo.service.impl.RetryServiceImpl - 测试retry15:21:31 INFO  [qtp1129243682-21]  com.demo.service.impl.TestServiceImpl - 成功啦啦啦啦啦啦啦啦15:21:31 INFO  [qtp1129243682-21]  com.atomikos.icatch.imp.CompositeTransactionImp - commit() done (by application) of transaction 10.3.5.31.tm0000100002

要测试@Recover,即一直异常,只需要把RetryServiceImpl里的if(i==3)改为if(i==6),把调用service里if(s.equals(“3”))改完if(s.equals(“6)),然后重新访问,日志:
[java] view plain copy
print?
  1. 15:26:54 WARN  [qtp1870436181-20]  com.atomikos.icatch.imp.TransactionServiceImp - Attempt to create a transaction with a timeout that exceeds com.atomikos.icatch.max_timeout - truncating to: 300000  
  2. 15:26:54 INFO  [qtp1870436181-20]  com.atomikos.icatch.imp.BaseTransactionManager - createCompositeTransaction ( 10000000 ): created new ROOT transaction with id 10.3.5.31.tm0000100003  
  3. 15:26:54 INFO  [qtp1870436181-20]  com.demo.service.impl.RetryServiceImpl - 测试retry  
  4. 15:26:55 INFO  [qtp1870436181-20]  com.demo.service.impl.RetryServiceImpl - 测试retry  
  5. 15:26:56 INFO  [qtp1870436181-20]  com.demo.service.impl.RetryServiceImpl - 测试retry  
  6. 15:26:57 INFO  [qtp1870436181-20]  com.demo.service.impl.RetryServiceImpl - 测试retry  
  7. 15:26:57 INFO  [qtp1870436181-20]  com.demo.service.impl.RetryServiceImpl - 连接超时  
  8. 15:26:57 INFO  [qtp1870436181-20]  com.demo.service.impl.TestServiceImpl - 成功啦啦啦啦啦啦啦啦  
  9. 15:26:57 INFO  [qtp1870436181-20]  com.atomikos.icatch.imp.CompositeTransactionImp - commit() done (by application) of transaction 10.3.5.31.tm0000100003  
15:26:54 WARN  [qtp1870436181-20]  com.atomikos.icatch.imp.TransactionServiceImp - Attempt to create a transaction with a timeout that exceeds com.atomikos.icatch.max_timeout - truncating to: 30000015:26:54 INFO  [qtp1870436181-20]  com.atomikos.icatch.imp.BaseTransactionManager - createCompositeTransaction ( 10000000 ): created new ROOT transaction with id 10.3.5.31.tm000010000315:26:54 INFO  [qtp1870436181-20]  com.demo.service.impl.RetryServiceImpl - 测试retry15:26:55 INFO  [qtp1870436181-20]  com.demo.service.impl.RetryServiceImpl - 测试retry15:26:56 INFO  [qtp1870436181-20]  com.demo.service.impl.RetryServiceImpl - 测试retry15:26:57 INFO  [qtp1870436181-20]  com.demo.service.impl.RetryServiceImpl - 测试retry15:26:57 INFO  [qtp1870436181-20]  com.demo.service.impl.RetryServiceImpl - 连接超时15:26:57 INFO  [qtp1870436181-20]  com.demo.service.impl.TestServiceImpl - 成功啦啦啦啦啦啦啦啦15:26:57 INFO  [qtp1870436181-20]  com.atomikos.icatch.imp.CompositeTransactionImp - commit() done (by application) of transaction 10.3.5.31.tm0000100003


原创粉丝点击