spring retry实现方法请求重试的使用步骤

目录
  • 1 spring-retry是什么?
  • 2 使用步骤
    • 2.1 引入maven库
    • 2.2 在spring启动类上开启重试功能
    • 2.3 公共业务代码
    • 2.4 传统的重试做法
    • 2.5 使用spring-retry的命令式编码
      • 2.5.1 定义重试监听器
      • 2.5.2 定义重试配置
      • 2.5.3 命令式编码
    • 2.6使用spring-retry的注解式编码
  • 3 SpringBoot整合spring-retry
    • 3.1 添加@EnableRetry注解
    • 3.2 接口实现
    • 3.3 添加@Retryable注解
    • 3.4 Controller测试代码
    • 3.5 发送请求
    • 3.6 补充:@Recover

1 spring-retry是什么?

以往我们在进行网络请求的时候,需要考虑网络异常的情况,本文就介绍了利用spring-retry,是spring提供的一个重试框架,原本自己实现的重试机制,现在spring帮封装好提供更加好的编码体验。

2 使用步骤

2.1 引入maven库

代码如下(示例):

	<dependency>
	    <groupId>org.springframework.retry</groupId>
	    <artifactId>spring-retry</artifactId>
	</dependency>
	<dependency>
	    <groupId>org.springframework</groupId>
	    <artifactId>spring-aspects</artifactId>
	    <version>4.3.9.RELEASE</version>
	</dependency>

2.2 在spring启动类上开启重试功能

提示:添加@EnableRetry注解开启
@SpringBootApplication
@EnableRetry
public class SpringRetryDemoApplication {
    public static SpringRetryAnnotationService springRetryAnnotationService;
    public static SpringRetryImperativeService springRetryImperativeService;
    public static TranditionalRetryService tranditionalRetryService;
    @Autowired
    public void setSpringRetryAnnotationService(SpringRetryAnnotationService springRetryAnnotationService) {
        SpringRetryDemoApplication.springRetryAnnotationService = springRetryAnnotationService;
    }
    @Autowired
    public void setSpringRetryImperativeService(SpringRetryImperativeService springRetryImperativeService) {
        SpringRetryDemoApplication.springRetryImperativeService = springRetryImperativeService;
    }
    @Autowired
    public void setTranditionalRetryService(TranditionalRetryService tranditionalRetryService) {
        SpringRetryDemoApplication.tranditionalRetryService = tranditionalRetryService;
    }
    public static void main(String[] args) {
        SpringApplication.run(SpringRetryDemoApplication.class, args);
        springRetryAnnotationService.test();
        springRetryImperativeService.test();
        tranditionalRetryService.test();
    }
}

2.3 公共业务代码

@Service
@Slf4j
public class CommonService {
    public void test(String before) {
        for (int i = 0; i < 10; i++) {
            if (i == 2) {
                log.error("{}:有异常哦,我再试多几次看下还有没异常", before);
                throw new RuntimeException();
            }
            log.info("{}:打印次数: {}", before, i + 1);
        }
    }

    public void recover(String before) {
        log.error("{}:还是有异常,程序有bug哦", before);
    }
}

2.4 传统的重试做法

@Service
@Slf4j
public class TranditionalRetryService {
    @Autowired
    CommonService commonService;

    public void test() {
        // 定义重试次数以及重试时间间隔
        int retryCount = 3;
        int retryTimeInterval = 3;
        for (int r = 0; r < retryCount; r++) {
            try {
                commonService.test("以前的做法");
            } catch (RuntimeException e) {
                if (r == retryCount - 1) {
                    commonService.recover("以前的做法");
                    return;
                }
                try {
                    Thread.sleep(retryTimeInterval * 1000);
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
            }

        }

    }
}

2.5 使用spring-retry的命令式编码

2.5.1 定义重试监听器

提示:监听重试过程的生命周期
@Slf4j
public class MyRetryListener extends RetryListenerSupport {
    @Override
    public <T, E extends Throwable> void close(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
        log.info("监听到重试过程关闭了");
        log.info("=======================================================================");
    }

    @Override
    public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
        log.info("监听到重试过程错误了");
    }

    @Override
    public <T, E extends Throwable> boolean open(RetryContext context, RetryCallback<T, E> callback) {
        log.info("=======================================================================");
        log.info("监听到重试过程开启了");
        return true;
    }
}

2.5.2 定义重试配置

提示:配置RetryTemplate重试模板类
@Configuration
public class RetryConfig {
    @Bean
    public RetryTemplate retryTemplate() {
        // 定义简易重试策略,最大重试次数为3次,重试间隔为3s
        RetryTemplate retryTemplate = RetryTemplate.builder()
                .maxAttempts(3)
                .fixedBackoff(3000)
                .retryOn(RuntimeException.class)
                .build();
        retryTemplate.registerListener(new MyRetryListener());
        return retryTemplate;
    }
}

2.5.3 命令式编码

@Service
@Slf4j
public class SpringRetryImperativeService {
    @Autowired
    RetryTemplate retryTemplate;
    @Autowired
    CommonService commonService;

    public void test() {
        retryTemplate.execute(
                retry -> {
                    commonService.test("命令式");
                    return null;
                },
                recovery -> {
                    commonService.recover("命令式");
                    return null;
                }
        );
    }
}

2.6使用spring-retry的注解式编码

@Service
@Slf4j
public class SpringRetryAnnotationService {
    @Autowired
    CommonService commonService;

    /**
     * 如果失败,定义重试3次,重试间隔为3s,指定恢复名称,指定监听器
     */
    @Retryable(value = RuntimeException.class, maxAttempts = 3, backoff = @Backoff(value = 3000L), recover = "testRecover", listeners = {"myRetryListener"})
    public void test() {
        commonService.test("注解式");
    }

    @Recover
    public void testRecover(RuntimeException runtimeException) {
        commonService.recover("注解式");
    }
}

3 SpringBoot整合spring-retry

我们使用SpringBoot来整合spring-retry组件实现重试机制。

3.1 添加@EnableRetry注解

在主启动类Application上添加@EnableRetry注解,实现对重试机制的支持

@SpringBootApplication
@EnableRetry
public class RetryApplication {

    public static void main(String[] args) {

        SpringApplication.run(RetryApplication.class, args);
    }

}

注意:@EnableRetry也可以使用在配置类、ServiceImpl类、方法上

3.2 接口实现

注意:接口类一定不能少,在接口类中定义你需要实现重试的方法,否则可能会无法实现重试功能

我的测试接口类如下:

public interface RetryService {    public String testRetry()  throws Exception;}

3.3 添加@Retryable注解

我们针对需要实现重试的方法上添加@Retryable注解,使该方法可以实现重试,这里我列出ServiceImpl中的一个方法:

@Service
public class RetryServiceImpl implements RetryService {
    @Override
    @Retryable(value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 2000,multiplier = 1.5))
    public String testRetry() throws Exception {

        System.out.println("开始执行代码:"+ LocalTime.now());
        int code = 0;
        // 模拟一直失败
        if(code == 0){
           // 这里可以使自定义异常,@Retryable中value需与其一致
            throw new Exception("代码执行异常");
        }
        System.out.println("代码执行成功");
        return "success";
    }
}

说明:@Retryable配置元数据情况:
value :针对指定抛出的异常类型,进行重试,这里指定的是Exception
maxAttempts :配置最大重试次数,这里配置为3次(包含第一次和最后一次)
delay: 第一次重试延迟间隔,这里配置的是2s
multiplier :每次重试时间间隔是前一次几倍,这里是1.5倍

3.4 Controller测试代码

@RestController
@RequestMapping("/test")
public class TestController {
    //  一定要注入接口,通过接口去调用方法
    @Autowired
    private RetryService retryService;

    @GetMapping("/retry")
    public String testRetry() throws Exception {
        return retryService.testRetry();
    }
}

3.5 发送请求

发送请求后,我们发现后台打印情况,确实重试了3次,并且在最后一次重试失败的情况下,才抛出异常,具体如下(可以注意下时间间隔)

3.6 补充:@Recover

一般情况下,我们重试最大设置的次数后,仍然失败抛出异常,我们会通过全局异常处理类进行统一处理,但是我们其实也可以自行处理,可以通过@Recover注解来实现,具体如下:

@Service
public class RetryServiceImpl implements RetryService {

    @Retryable(value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 2000,multiplier = 1.5))
    public String testRetry() throws Exception {

        System.out.println("开始执行代码:"+ LocalTime.now());
        int code = 0;
        if(code == 0){
            // 这里可以使自定义异常,@Retryable中value需与其一致
            throw new Exception("代码执行异常");
        }
        System.out.println("代码执行成功");
        return "success";
    }

    /**
     * 最终重试失败处理
     * @param e
     * @return
     */
    @Recover
    public String recover(Exception e){

        System.out.println("代码执行重试后依旧失败");
        return "fail";
    }
}

注意:
1)@Recover的方法中的参数异常类型需要与重试方法中一致
2)该方法的返回值类型与重试方法保持一致

再次测试如下(发现不会再抛出异常)

到此这篇关于spring retry实现方法请求重试的文章就介绍到这了,更多相关spring retry方法请求重试内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • SpringRetry重试框架的具体使用

    目录 一.环境搭建 二.RetryTemplate 2.1 RetryTemplate 2.2 RetryListener 2.3 回退策略 2.3.1 FixedBackOffPolicy 2.3.2 ExponentialBackOffPolicy 2.4 重试策略 2.5 RetryCallback 2.6 核心使用 三.EnableRetry 四.Retryable spring retry主要实现了重试和熔断. 不适合重试的场景: 参数校验不合法.写操作等(要考虑写是否幂等)都不适合重

  • 浅谈spring的重试机制无效@Retryable@EnableRetry

    spring-retry模块支持方法和类.接口.枚举级别的重试 方式很简单,引入pom包 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>lastest</version> </parent> <dependency> &

  • SpringBoot整合spring-retry实现接口请求重试机制及注意事项

    目录 一.重试机制 二.重试机制要素 三.重试机制注意事项 四.SpringBoot整合spring-retry 1)添加依赖 2)添加@EnableRetry注解 3)添加@Retryable注解 4)Controller测试代码 5)发送请求 6)补充:@Recover 一.重试机制 由于网络不稳定或网络抖动经常会造成接口请求失败的情况,当我们再去尝试就成功了,这就是重试机制. 其主要目的就是要尽可能地提高请求成功的概率,但一般情况下,我们请求第一次失败,代码运行就抛出异常结束了,如果想再次

  • 详解重试框架Spring retry实践

    spring retry是从spring batch独立出来的一个能功能,主要实现了重试和熔断.对于重试是有场景限制的,不是什么场景都适合重试,比如参数校验不合法.写操作等(要考虑写是否幂等)都不适合重试.远程调用超时.网络突然中断可以重试.在微服务治理框架中,通常都有自己的重试与超时配置,比如dubbo可以设置retries=1,timeout=500调用失败只重试1次,超过500ms调用仍未返回则调用失败.在spring retry中可以指定需要重试的异常类型,并设置每次重试的间隔以及如果重

  • Spring重试支持Spring Retry的方法

    本文介绍了Spring重试支持Spring Retry的方法,分享给大家,具体如下: 第一步.引入maven依赖 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.3.RELEASE</version> </parent> &l

  • spring retry实现方法请求重试的使用步骤

    目录 1 spring-retry是什么? 2 使用步骤 2.1 引入maven库 2.2 在spring启动类上开启重试功能 2.3 公共业务代码 2.4 传统的重试做法 2.5 使用spring-retry的命令式编码 2.5.1 定义重试监听器 2.5.2 定义重试配置 2.5.3 命令式编码 2.6使用spring-retry的注解式编码 3 SpringBoot整合spring-retry 3.1 添加@EnableRetry注解 3.2 接口实现 3.3 添加@Retryable注解

  • Spring boot使用spring retry重试机制的方法示例

    当我们调用接口的时候由于网络原因可能失败,再尝试就成功了,这就是重试机制.非幂等的情况下要小心使用重试. tips:幂等性 HTTP/1.1中对幂等性的定义是:一次和多次请求某一个资源对于资源本身应该具有同样的结果(网络超时等问题除外).也就是说,其任意多次执行对资源本身所产生的影响均与一次执行的影响相同. 注解方式使用Spring Retry (一)Maven依赖 <!-- 重试机制 --> <dependency> <groupId>org.springframew

  • Spring Retry 重试实例详解

    spring-retry是什么? spring-retry是spring提供的一个重试框架,原本自己实现的重试机制,现在spring帮封装好提供更加好的编码体验. 重试的使用场景比较多,比如调用远程服务时,由于网络或者服务端响应慢导致调用超时,此时可以多重试几次.用定时任务也可以实现重试的效果,但比较麻烦,用Spring Retry的话一个注解搞定所有.话不多说,先看演示. 首先引入依赖 <dependency> <groupId>org.springframework.retry

  • Spring Retry重试框架的使用讲解

    目录 命令式 声明式(注解方式) 1. 用法 2. RetryTemplate 3. RecoveryCallback 4. Listeners 5. 声明式重试 重试的使用场景比较多,比如调用远程服务时,由于网络或者服务端响应慢导致调用超时,此时可以多重试几次.用定时任务也可以实现重试的效果,但比较麻烦,用Spring Retry的话一个注解搞定所有.话不多说,先看演示. 首先引入依赖 <dependency> <groupId>org.springframework.retry

  • 详解Spring Retry实现原理

    在前面这篇博客中介绍了Spring Retry的使用,本文通过一个简单的例子演示Spring Retry的实现原理,例子中定义的注解只包含重试次数属性,实际上Spring Retry中注解可设置属性要多的多,单纯为了讲解原理,所以弄简单点,关于Spring Retry可查阅相关文档.博客. 注解定义 package retry.annotation; import java.lang.annotation.*; /** * Created by Jack.wu on 2016/9/30. */

  • spring retry方法调用失败重试机制示例解析

    目录 前言 1.导入依赖 2.注解的使用 3.开启重试 补充,手动声明式重试: 前言 很多场景会用到重试的机制,比如:rpc服务调用失败重试,文件上传oss失败重试,http接口调用失败重试,支付回调失败重试等等,一切因为网络,非逻辑性错误等不确定因素引起的失败都可以加上重试的机制,来增强系统的健壮性,博主也处理过文件上传到第三方oss服务失败增加重试的事例,在这之前不知道spring有个spring-retry项目,所以采用的是限制次数的递归调用的方式来解决的. 现在我们来看看spring b

  • 从零搭建脚手架之集成Spring Retry实现失败重试和熔断器模式(实战教程)

    目录 背景 实战 添加依赖 启用重试 @Recover @CircuitBreaker 高级实战 方式一 @CircuitBreaker + RetryTemplate 方式二 @CircuitBreaker + @Retryable 参考 背景 在我们的大多数项目中,会有一些场景需要重试操作,而不是立即失败,让系统更加健壮且不易发生故障. 场景如下: 瞬时网络抖动故障 服务器重启 偶发死锁 某些上游的异常或者响应码,需要进行重试 远程调用 从数据库中获取或存储数据 以上皆为瞬时故障. 也会有一

  • Spring的异常重试框架Spring Retry简单配置操作

    相关api见:点击进入 /* * Copyright 2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *

随机推荐