spring retry 使用

1.  场景

 
     系统方法调用时无状态的,同时因为网络原因,或者系统暂时故障,进行的重试
 
2. maven 依赖
 
  1. <projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  3. <modelVersion>4.0.0</modelVersion>
  4. <groupId>com.dalong.spring.io</groupId>
  5. <artifactId>springretrydemo</artifactId>
  6. <version>0.0.1-SNAPSHOT</version>
  7. <parent>
  8. <groupId>org.springframework.boot</groupId>
  9. <artifactId>spring-boot-starter-parent</artifactId>
  10. <version>1.4.2.RELEASE</version>
  11. </parent>
  12. <dependencies>
  13. <dependency>
  14. <groupId>org.springframework.retry</groupId>
  15. <artifactId>spring-retry</artifactId>
  16. <version>1.1.5.RELEASE</version><!--$NO-MVN-MAN-VER$ -->
  17. </dependency>
  18. <dependency>
  19. <groupId>org.springframework.boot</groupId>
  20. <artifactId>spring-boot-starter-test</artifactId>
  21. <scope>test</scope>
  22. </dependency>
  23. <dependency>
  24. <groupId>org.apache.geronimo.bundles</groupId>
  25. <artifactId>aspectjweaver</artifactId>
  26. <version>1.6.8_2</version>
  27. </dependency>
  28. <dependency>
  29. <groupId>org.springframework.boot</groupId>
  30. <artifactId>spring-boot-starter-web</artifactId>
  31. </dependency>
  32. </dependencies>
  33. <build>
  34. <plugins>
  35. <plugin>
  36. <groupId>org.springframework.boot</groupId>
  37. <artifactId>spring-boot-maven-plugin</artifactId>
  38. </plugin>
  39. <plugin>
  40. <artifactId>maven-compiler-plugin</artifactId>
  41. <version>3.1</version><!--$NO-MVN-MAN-VER$ -->
  42. <configuration>
  43. <source>1.8</source>
  44. <target>1.8</target>
  45. </configuration>
  46. </plugin>
  47. </plugins>
  48. </build>
  49. </project>
3. 定义 service  并标注retry 策略
 
     注解驱动,方法驱动
 
     
  1. @Service
  2. publicclassFirstService{
  3. @Retryable(value=RemoteAccessException.class,maxAttempts=3,backoff=@Backoff(delay =5000l,multiplier =1))
  4. publicString service(String value){
  5. // ... do something
  6. System.out.println("do something...");
  7. if(null==value||"".equals(value)){
  8. thrownewRemoteAccessException("RPC调用异常");
  9. }
  10. else{
  11. return"dalong demo info";
  12. }
  13. }
  14. @Recover
  15. publicString recover(RemoteAccessException e){
  16. // ... panic
  17. System.out.println(e.getMessage());
  18. System.out.println("rong method");
  19. return e.getMessage();
  20. }
  21. }
  使用retrytemplate
 
    
  1. @Service
  2. publicclassMyService2{
  3. @Autowired
  4. publicUserOperator userOperator;
  5. publicUserInfo getUserinfo()throwsTimeoutException{
  6. RetryTemplate template =newRetryTemplate();
  7. TimeoutRetryPolicy policy =newTimeoutRetryPolicy();
  8. policy.setTimeout(1000L);
  9. template.setRetryPolicy(policy);
  10. UserInfo result = template.execute(newRetryCallback<UserInfo,TimeoutException>(){
  11. @Override
  12. publicUserInfo doWithRetry(RetryContext context)throwsTimeoutException{
  13. // TODO Auto-generated method stub
  14. UserInfo info =null;
  15. info = userOperator.getUserinfo();
  16. return info;
  17. }
  18. },newRecoveryCallback<UserInfo>(){
  19. @Override
  20. publicUserInfo recover(RetryContext context)throwsException{
  21. // TODO Auto-generated method stub
  22. UserInfo inf =newUserInfo();
  23. inf.setDate(newDate());
  24. inf.setAge(333);
  25. inf.setInfo("default");
  26. return inf;
  27. }
  28. });
  29. return result;
  30. }
  31. }
UserOperator   服务
 
  1. @Service
  2. publicclassUserOperator{
  3. publicUserInfo getUserinfo()throwsTimeoutException{
  4. UserInfo info =newUserInfo();
  5. info.setDate(newDate());
  6. info.setAge(333);
  7. info.setInfo("dddddd");
  8. try{
  9. Thread.sleep(2000);
  10. }catch(InterruptedException e){
  11. // TODO Auto-generated catch block
  12. e.printStackTrace();
  13. thrownewTimeoutException("timeout");
  14. }
  15. return info;
  16. }
  17. }
4. rest api  调用
 
   
  1. @Autowired
  2. publicMyService2 myService2;
  3. @RequestMapping(value ="/user", method =RequestMethod.GET)
  4. publicObject getuser()throwsTimeoutException{
  5. UserInfo info =null;
  6. info = myService2.getUserinfo();
  7. return info;
  8. // return "this is demo";
  9. }
5. 类似的解决方案
 
    netflix 公司的hystrix ,目前spring  cloud 已经进行了集成封装,也可以单独进行使用。
 
6. 重试策略的说明
 
   
  1. org.springframework.retry.policy.SimpleRetryPolicy 
    该策略定义了对指定的异常进行若干次重试。默认情况下,对Exception异常及其子类重试3次。如果创建SimpleRetryPolicy并指定重试异常map,可以选择性重试或不进行重试。下面的代码定义了对TimeOutException进行重试
  2. org.springframework.retry.policy.NeverRetryPolicy 
    执行一次待执行操作,若出现异常后不进行重试。
  3. org.springframework.retry.policy.AlwaysRetryPolicy 
    异常后一直重试直到成功。
  4. org.springframework.retry.policy.TimeoutRetryPolicy 
    在执行execute方法时从open操作开始到调用TimeoutRetryPolicy的canRetry方法这之间所经过的时间。这段时间未超过TimeoutRetryPolicy定义的超时时间,那么执行操作,否则抛出异常。
  5. org.springframework.retry.policy.ExceptionClassifierRetryPolicy

    根据产生的异常选择重试策略。

  6. org.springframework.retry.policy.CompositeRetryPolicy 
    用户指定一组策略,随后根据optimistic选项来确认如何重试。

 
原文地址:https://www.cnblogs.com/rongfengliang/p/6253121.html