栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

关于Spring-Retry的使用

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

关于Spring-Retry的使用

关于Spring-Retry的使用
  • 1 Spring-Retry的使用
      • 1 Spring-Retry的简介
      • 2 Spring中的应用
        • 1 导入maven坐标
        • 2 添加被调用类
        • 3 添加测试类
      • 3 SpringBoot中的应用
        • 1 导入maven坐标
        • 2 添加一个管理类
        • 3 启动类上添加注解@EnableRetry
        • 4 添加测试类

1 Spring-Retry的使用 1 Spring-Retry的简介

在日常的一些场景中, 很多需要进行重试的操作.而spring-retry是spring提供的一个基于spring的重试框架,非常简单好用.

2 Spring中的应用 1 导入maven坐标
 
    org.springframework.retry
    spring-retry
    1.2.2.RELEASE
 
2 添加被调用类
@Slf4j
public class RetryDemo {

    public static boolean retryMethod(Integer param) {
        int i = new Random().nextInt(param);
        log.info("随机生成的数:{}", i);

        if (1 == i) {
            log.info("为1,返回true.");
            return true;
        } else if (i < 1) {
            log.info("小于1,抛出参数异常.");
            throw new IllegalArgumentException("参数异常");
        } else if (i > 1 && i < 10) {
            log.info("大于1,小于10,抛出参数异常.");
            return false;
        } else {
            //为其他
            log.info("大于10,抛出自定义异常.");
            throw new RemoteAccessException("大于10,抛出自定义异常");
        }
    }

}
3 添加测试类
@Slf4j
public class SpringRetryTest {

    
    private long fixedPeriodTime = 1000L;
    
    private int maxRetryTimes = 3;
    
    private Map, Boolean> exceptionMap = new HashMap<>();


    @Test
    public void test() {

        // 1 添加异常的处理结果 true为需要重试 false为不需要重试
        exceptionMap.put(RemoteAccessException.class, true);

        // 2 构建重试模板实例
        RetryTemplate retryTemplate = new RetryTemplate();

        // 3 设置重试回退操作策略  设置重试间隔时间
        FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();
        backOffPolicy.setBackOffPeriod(fixedPeriodTime);

        // 4 设置重试策略  设置重试次数 设置异常处理结果
        SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy(maxRetryTimes, exceptionMap);

        //5 重试模板添加重试策略 添加回退操作策略
        retryTemplate.setRetryPolicy(retryPolicy);
        retryTemplate.setBackOffPolicy(backOffPolicy);
    
        // 6 调用方法
        Boolean resp = retryTemplate.execute(
                // RetryCallback 重试回调方法
                retryContext -> {
                    boolean result = RetryDemo.retryMethod(110);
                    log.info("方法返回结果= {}", result);
                    return result;
                },
                // RecoveryCallback 异常回调方法
                retryContext -> {
                    //
                    log.info("超过最大重试次数或者抛出了未定义的异常!!!");
                    return false;
                }
        );

        log.info("接口返回结果 = {}",resp);

    }

}

从代码的书写注解可以看到,RetryTemplate对象是Spring-Retry框架的重试执行者, 由它添加重试策略,回退操作策略等(注释第五步).RetryTemplate执行重试方法(注释第六步),通过execute方法, 传入的参数是重试回调逻辑对象RetryCallback 和执行操作结束的恢复对象RecoveryCallback. 且可以切换添加的异常种类, 得知,只有添加过相应的异常,才会触发重试操作,否则直接调用RecoveryCallback对象方法.

RetryTemplate的部分源码:

	
	@Override
	public final  T execute(RetryCallback retryCallback,
			RecoveryCallback recoveryCallback) throws E {
		return doExecute(retryCallback, recoveryCallback, null);
	}

RetryTemplate添加重试策略源码:

	
	public void setRetryPolicy(RetryPolicy retryPolicy) {
		this.retryPolicy = retryPolicy;
	}

RetryPolicy接口的实现类:

AlwaysRetryPolicy:允许无限重试,直到成功,可能会导致死循环

CircuitBreakerRetryPolicy:有熔断功能的重试策略,需设置3个参数openTimeout、resetTimeout和delegate

CompositeRetryPolicy:组合重试策略,有两种组合方式,乐观组合重试策略是指只要有一个策略允许即可以重试,
悲观组合重试策略是指只要有一个策略不允许即可以重试,但不管哪种组合方式,组合中的每一个策略都会执行
    
ExceptionClassifierRetryPolicy:设置不同异常的重试策略,类似组合重试策略,区别在于这里只区分不同异常的重试
    
NeverRetryPolicy:只允许调用RetryCallback一次,不允许重试
    
SimpleRetryPolicy:固定次数重试策略,默认重试最大次数为3次,RetryTemplate默认使用的策略

TimeoutRetryPolicy:超时时间重试策略,默认超时时间为1秒,在指定的超时时间内允许重试

RetryTemplate添加回退策略源码:

	
	public void setBackOffPolicy(BackOffPolicy backOffPolicy) {
		this.backOffPolicy = backOffPolicy;
	}

BackOffPolicy的实现类:

ExponentialBackOffPolicy:指数退避策略,需设置参数sleeper、initialInterval、maxInterval和multiplier,initialInterval指定初始休眠时间,默认100毫秒,maxInterval指定最大休眠时间,默认30秒,multiplier指定乘数,即下一次休眠时间为当前休眠时间*multiplier

ExponentialRandomBackOffPolicy:随机指数退避策略,引入随机乘数可以实现随机乘数回退

FixedBackOffPolicy:固定时间的退避策略,需设置参数sleeper和backOffPeriod,sleeper指定等待策略,默认是Thread.sleep,即线程休眠,backOffPeriod指定休眠时间,默认1秒
    
NoBackOffPolicy:无退避算法策略,每次重试时立即重试

UniformRandomBackOffPolicy:随机时间退避策略,需设置sleeper、minBackOffPeriod和maxBackOffPeriod,该策略在[minBackOffPeriod,maxBackOffPeriod之间取一个随机休眠时间,minBackOffPeriod默认500毫秒,maxBackOffPeriod默认1500毫秒
3 SpringBoot中的应用 1 导入maven坐标
 
    org.springframework.retry
    spring-retry
    1.2.2.RELEASE
 

 
    org.aspectj
    aspectjweaver
    1.9.1
 
2 添加一个管理类
@Service
@Slf4j
public class SpringRetryDemo {


    
    // delay=2000L表示延迟2秒 multiplier=2表示两倍 即第一次重试2秒后,第二次重试4秒后,第三次重试8秒后
    @Retryable(value = {RemoteAccessException.class}, maxAttempts = 3, backoff = @Backoff(delay = 2000L, multiplier = 2))
    public boolean call(Integer param) {
        return RetryDemo.retryMethod(param);
    }

    
    @Recover
    public boolean recover(Exception e, Integer param) {
        log.info("请求参数为: ", param);
        log.info("超过最大重试次数或抛出没有指定重试的异常, e = {} ", e.getMessage());
        return false;
    }

}
3 启动类上添加注解@EnableRetry
@SpringBootApplication
@EnableRetry
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}    
4 添加测试类
@RunWith(SpringRunner.class)
@SpringBootTest(classes = DemoApplication.class)
@Slf4j
public class DemoApplicationTests {

    @Autowired
    private SpringRetryDemo springRetryDemo;

    @Test
    public void testRetry() {
        boolean result = springRetryDemo.call(110);
        log.info("方法返回结果为: {}", result);
    }
}

注解说明:

@Enableretry注解,启用重试功能(默认是否基于子类代理,默认是否, 即是基于Java接口代理)

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@EnableAspectJAutoProxy(proxyTargetClass = false)
@import(RetryConfiguration.class)
@documented
public @interface EnableRetry {

	
	boolean proxyTargetClass() default false;

}

@Retryable注解, 标记的方法发生异常时会重试

  • value 指定发生的异常进行重试
  • include 与value一样,默认为空,当exclude同时为空时,所有异常都重试
  • exclude 指定异常不重试,默认为空,当include同时为空,所有异常都重试
  • maxAttemps 重试次数,默认3
  • backoff 重试补充机制 默认是@Backoff()注解
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@documented
public @interface Retryable {

	
	String interceptor() default "";

	
	Class[] value() default {};

	
	Class[] include() default {};

	
	Class[] exclude() default {};

	
	String label() default "";

	
	boolean stateful() default false;

	
	int maxAttempts() default 3;

	
	String maxAttemptsexpression() default "";

	
	Backoff backoff() default @Backoff();

	
	String exceptionexpression() default "";

}

@Backoff注解

  • delay 延迟多久后重试
  • multiplier 延迟的倍数
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@import(RetryConfiguration.class)
@documented
public @interface Backoff {

	
	long value() default 1000;

	
	long delay() default 0;

	
	long maxDelay() default 0;

	
	double multiplier() default 0;

	
	String delayexpression() default "";

	
	String maxDelayexpression() default "";

	
	String multiplierexpression() default "";

	
	boolean random() default false;

}

@Recover注解

  • 当重试达到规定的次数后,被注解标记的方法将被调用, 可以在此方法中进行日志的记录等操作.(该方法的入参类型,返回值类型需要和重试方法保持一致)
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@import(RetryConfiguration.class)
@documented
public @interface Recover {
}

参考资料:

https://blog.csdn.net/zzzgd_666/article/details/84377962

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/459306.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号