Spring Retry使用小结

1、背景

日常开发中经常会下发接口回调通知失败、远程调用失败等等,这些错误可能是因为网络波动造成的,等待过后重处理就能成功。通常来说,会用try/catch,while循环之类的语法来进行重处理,但是这样的做法缺乏统一性,并且不是很方便,要多写很多代码。然而spring-retry却可以通过注解,在不入侵原有业务逻辑代码的方式下,优雅的实现重处理功能。

2、使用步骤

2.1、pom.xml中引入相关依赖

引入spring-retryspring-aspects依赖的最新版本

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.0</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.cnblogs.javalouvre</groupId>
    <artifactId>spring-retry-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-retry-demo</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</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>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

2.2、启用@Retryable

package com.cnblogs.javalouvre.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.retry.annotation.EnableRetry;

@Configuration
@EnableRetry
public class AppConfig {
}

2.3、在响应方法上加上注解

package com.cnblogs.javalouvre.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;

@Service
public class IndexService {

    private static final Logger log = LoggerFactory.getLogger(IndexService.class);

    /**
     * @Retryable注解标注,则发生对应错误,进行重试处理。
     *
     * 注解参数说明:
     *  1、retryFor 针对指定异常,进行重试处理
     *  2、backoff 重试策略
     *    2.1、delay 发起下次重试前时间间隔(单位:毫秒)
     *    2.2、multiplier 若此参数大于零,则重试时间间隔delay须乘于multiplier
     *  3、recover 指定重试次数用完后依然失败的处理句柄
     *  4、maxAttempts 最多尝试次数,默认3次
     */
    @Retryable(retryFor = Exception.class, backoff = @Backoff(delay = 5000L, multiplier = 1.5D), recover = "recoverDiv")
    public double div(int x, int y) {
        log.info("执行时间: {}", LocalDateTime.now());

        return x / y;
    }

    /**
     * 重试次数用完后续处理
     *
     * 对于@Recover注解的方法,须注意一下事项
     *  1、方法的返回值必须与@Retryable方法一致
     *  2、方法的第一个参数,必须是Throwable类型的,建议是与@Retryable配置的异常一致,其他的参数,需要哪个参数,写进去就可以了(@Recover方法中有的)
     *  3、该回调方法与重试方法写在同一个实现类里面
     */
    @Recover
    private double recoverDiv(Exception e, int x, int y) {
        log.info("异常 => {}", e.getMessage());

        return 0D;
    }
}

posted @ 2023-12-21 16:26  Bruce.Chang.Lee  阅读(7)  评论(0编辑  收藏  举报