Spring之Retry

业务场景:

  随着服务的模块化,软件架构中系统之间的接口调用也变得越来越多,由于网络抖动或者其他原因造成接口调用失败。没能达到理想效果。

解决方案:

  鉴于上述问题,我们第一时间可能想到的就是“重试”,在重试的过程中,我们需要考虑:

  1.重试的次数;

  2.每次重试间隔的时间;

  3.在达到最高重试次数后依旧失败我们的处理方案

  4.。。。。。。。。;

 

Spring提供了retry机制,使得我们不用自己去重复的造轮子,使用简单的注解即可实现以上逻辑。

主要注解:

@EnableRetry:

  

根据源码,只有一个参数。该参数指明是否使用CGLIB来代理;

@Retryable:

    value:指定处理的异常类

            include:指定处理的异常类和value一样,默认为空,当exclude也为空时,默认所有异常

            exclude:指定异常不处理,默认空,当include也为空时,默认所有异常

            maxAttempts:最大重试次数。默认3次

    maxAttemptsExpression: 计算最大重试次数的表达式,包含首次失败,默认为3

            backoff: 重试等待策略。默认使用@Backoff注解

@Backoff 重试等待策略:

           不设置参数时,默认使用FixedBackOffPolicy(指定等待时间),重试等待1000ms

           设置delay,使用FixedBackOffPolicy(指定等待时间),重试等待填写的时间

           设置delay和maxDealy时,重试等待在这两个值之间均态分布

           设置delay、maxDealy、multiplier,使用 ExponentialBackOffPolicy(指数级重试间隔的实现 ),multiplier即指定延迟倍数,比如delay=5000l,multiplier=2,则第一次重试为5秒,第二次为10秒,第三次为20秒……

@Recover:

       用于@Retryable重试失败后处理方法,此注解注释的方法参数一定要是@Retryable抛出的异常,否则无法识别,可以在该方法中进行日志处理。

代码示例:

  1.首先引入需要的jar包:示例基于SpringBoot,且SpringRetry机制依赖于AOP:  

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.0.RELEASE</version>
    </parent>

    <!-- Add typical dependencies for a web application -->
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.retry</groupId>
            <artifactId>spring-retry</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
    </dependencies>

启动类:

@SpringBootApplication
@EnableRetry
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class,args);
    }
}

service:

@Service
public class DemoService {
    @Retryable(value = RuntimeException.class,maxAttempts = 4)
    public void service(){
        System.out.println("开始调用服务...");
        throw new RuntimeException("服务调用异常");
    }
    @Recover
    private void callback(RuntimeException e){
        System.out.println(e.getMessage());
    }

}

测试类:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = Application.class)
public class ServiceTest {
    @Autowired
    private DemoService service;
    @Test
    public void test(){
        service.service();
    }
}

测试结果:

猜你喜欢

转载自www.cnblogs.com/funmans/p/10058110.html