文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Spring Retry重试框架如何使用

2023-07-04 12:27

关注

这篇“Spring Retry重试框架如何使用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Spring Retry重试框架如何使用”文章吧。

首先引入依赖

<dependency>    <groupId>org.springframework.retry</groupId>    <artifactId>spring-retry</artifactId>    <version>1.3.4</version></dependency><dependency>    <groupId>org.aspectj</groupId>    <artifactId>aspectjweaver</artifactId>    <version>1.9.9.1</version></dependency>

使用方式有两种:命令式和声明式

命令式

@GetMapping("/hello")public String hello(@RequestParam("code") Integer code) throws Throwable {    RetryTemplate retryTemplate = RetryTemplate.builder()            .maxAttempts(3)            .fixedBackoff(1000)            .retryOn(RemoteAccessException.class)            .build();    retryTemplate.registerListener(new MyRetryListener());    String resp = retryTemplate.execute(new RetryCallback<String, Throwable>() {        @Override        public String doWithRetry(RetryContext context) throws Throwable {            return helloService.hello(code);        }    });    return resp;}

定义一个RetryTemplate,然后调用execute方法,可配置项比较多,不一一列举

真正使用的时候RetryTemplate可以定义成一个Bean,例如:

@Configurationpublic class RetryConfig {    @Bean    public RetryTemplate retryTemplate() {        RetryTemplate retryTemplate = RetryTemplate.builder()                .maxAttempts(3)                .fixedBackoff(1000)                .withListener(new MyRetryListener())                .retryOn(RemoteAccessException.class)                .build();        return retryTemplate;    }}

业务代码:

@Overridepublic String hello(int code) {    if (0 == code) {        System.out.println("出错了");        throw new RemoteAccessException("出错了");    }    System.out.println("处理完成");    return "ok";}

Spring Retry重试框架如何使用

Spring Retry重试框架如何使用

Spring Retry重试框架如何使用

监听器实现:

package com.example.retry.listener;import org.springframework.retry.RetryCallback;import org.springframework.retry.RetryContext;import org.springframework.retry.RetryListener;public class MyRetryListener implements RetryListener {    @Override    public <T, E extends Throwable> boolean open(RetryContext context, RetryCallback<T, E> callback) {        System.out.println("open");        return true;    }    @Override    public <T, E extends Throwable> void close(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {        System.out.println("close");    }    @Override    public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {        System.out.println("error");    }}

声明式(注解方式)

@Retryable(value = Exception.class, maxAttempts = 2, backoff = @Backoff(value = 1000, delay = 2000, multiplier = 0.5))@Overridepublic String hi(int code) {    System.out.println("方法被调用");    int a = 1/code;    return "ok";}@Recoverpublic String hiRecover(Exception ex, int code) {    System.out.println("重试结束");    return "asdf";}

这里需要主要的几点

@GetMapping("/hi")public String hi(@RequestParam("code") Integer code) {    return helloService.hi(code);}

Spring Retry重试框架如何使用

Spring Retry重试框架如何使用

Spring Retry重试框架如何使用

Spring Retry重试框架如何使用

1. 用法

声明式

@Configuration@EnableRetrypublic class Application {}@Serviceclass Service {    @Retryable(RemoteAccessException.class)    public void service() {        // ... do something    }    @Recover    public void recover(RemoteAccessException e) {       // ... panic    }}

命令式

RetryTemplate template = RetryTemplate.builder().maxAttempts(3).fixedBackoff(1000).retryOn(RemoteAccessException.class).build();template.execute(ctx -> {    // ... do something});

2. RetryTemplate

为了自动重试,Spring Retry 提供了 RetryOperations 重试操作策略

public interface RetryOperations {    <T> T execute(RetryCallback<T> retryCallback) throws Exception;    <T> T execute(RetryCallback<T> retryCallback, RecoveryCallback<T> recoveryCallback)        throws Exception;    <T> T execute(RetryCallback<T> retryCallback, RetryState retryState)        throws Exception, ExhaustedRetryException;    <T> T execute(RetryCallback<T> retryCallback, RecoveryCallback<T> recoveryCallback,        RetryState retryState) throws Exception;}

基本回调是一个简单的接口,允许插入一些要重试的业务逻辑:

public interface RetryCallback<T> {    T doWithRetry(RetryContext context) throws Throwable;}

回调函数被尝试,如果失败(通过抛出异常),它将被重试,直到成功或实现决定中止。

RetryOperations最简单的通用实现是RetryTemplate

RetryTemplate template = new RetryTemplate();TimeoutRetryPolicy policy = new TimeoutRetryPolicy();policy.setTimeout(30000L);template.setRetryPolicy(policy);Foo result = template.execute(new RetryCallback<Foo>() {    public Foo doWithRetry(RetryContext context) {        // Do stuff that might fail, e.g. webservice operation        return result;    }});

从Spring Retry 1.3开始,RetryTemplate支持流式配置:

RetryTemplate.builder()      .maxAttempts(10)      .exponentialBackoff(100, 2, 10000)      .retryOn(IOException.class)      .traversingCauses()      .build();RetryTemplate.builder()      .fixedBackoff(10)      .withinMillis(3000)      .build();RetryTemplate.builder()      .infiniteRetry()      .retryOn(IOException.class)      .uniformRandomBackoff(1000, 3000)      .build();

3. RecoveryCallback

当重试耗尽时,RetryOperations可以将控制传递给不同的回调:RecoveryCallback。

Foo foo = template.execute(new RetryCallback<Foo>() {    public Foo doWithRetry(RetryContext context) {        // business logic here    },  new RecoveryCallback<Foo>() {    Foo recover(RetryContext context) throws Exception {          // recover logic here    }});

4. Listeners

public interface RetryListener {    void open(RetryContext context, RetryCallback<T> callback);    void onSuccess(RetryContext context, T result);    void onError(RetryContext context, RetryCallback<T> callback, Throwable e);    void close(RetryContext context, RetryCallback<T> callback, Throwable e);}

在最简单的情况下,open和close回调在整个重试之前和之后,onSuccess和onError应用于个别的RetryCallback调用,onSuccess方法在成功调用回调之后被调用。

5. 声明式重试

有时,你希望在每次业务处理发生时都重试一些业务处理。这方面的典型例子是远程服务调用。Spring Retry提供了一个AOP拦截器,它将方法调用封装在RetryOperations实例中。RetryOperationsInterceptor执行被拦截的方法,并根据提供的RepeatTemplate中的RetryPolicy在失败时重试。

你可以在 @Configuration 类上添加一个 @EnableRetry 注解,并且在你想要进行重试的方法(或者类)上添加 @Retryable 注解,还可以指定任意数量的重试监听器。

@Configuration@EnableRetrypublic class Application {    @Bean    public Service service() {        return new Service();    }    @Bean public RetryListener retryListener1() {        return new RetryListener() {...}    }    @Bean public RetryListener retryListener2() {        return new RetryListener() {...}    }}@Serviceclass Service {    @Retryable(RemoteAccessException.class)    public service() {        // ... do something    }}

可以使用 @Retryable 的属性类控制 RetryPolicy 和 BackoffPolicy

@Serviceclass Service {    @Retryable(maxAttempts=12, backoff=@Backoff(delay=100, maxDelay=500))    public service() {        // ... do something    }}

如果希望在重试用尽时采用替代代码返回,则可以提供恢复方法。方法应该声明在与@Retryable实例相同的类中,并标记为@Recover。返回类型必须匹配@Retryable方法。恢复方法的参数可以包括抛出的异常和(可选地)传递给原始可重试方法的参数(或者它们的部分列表,只要在需要的最后一个之前不省略任何参数)。

@Serviceclass Service {    @Retryable(RemoteAccessException.class)    public void service(String str1, String str2) {        // ... do something    }    @Recover    public void recover(RemoteAccessException e, String str1, String str2) {       // ... error handling making use of original args if required    }}

若要解决可选择用于恢复的多个方法之间的冲突,可以显式指定恢复方法名称。

@Serviceclass Service {    @Retryable(recover = "service1Recover", value = RemoteAccessException.class)    public void service1(String str1, String str2) {        // ... do something    }    @Retryable(recover = "service2Recover", value = RemoteAccessException.class)    public void service2(String str1, String str2) {        // ... do something    }    @Recover    public void service1Recover(RemoteAccessException e, String str1, String str2) {        // ... error handling making use of original args if required    }    @Recover    public void service2Recover(RemoteAccessException e, String str1, String str2) {        // ... error handling making use of original args if required    }}

以上就是关于“Spring Retry重试框架如何使用”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯