Spring Boot实现重试

79 阅读2分钟

为了使处理 更加稳健 且不易失败,有时候 自动重试 失败的操作会有所帮助,以防后续尝试可能成功。容易受到这种处理的错误本质上是暂时性的,例如,对 Web 服务或 RMI 服务的远程调用由于网络故障而失败,或者数据库更新中的DeadLockLoserException

Spring Retry

Spring Retry是Spring框架提供的一个模块,它通过提供注解或编程方式的方式,帮助我们实现方法级别的重试机制。 image.png

Spring Retry在Spring Boot中的实现

添加依赖

<!--spring-retry依赖项 -- >
<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
    <version>2.0.3</version>
</dependency>

<!--spring-AOP依赖项 -- >
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>6.0.11</version>
</dependency>

启用Spring Retry

package guru.springframework;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.retry.annotation.EnableRetry;

@EnableRetry
@SpringBootApplication
public class SpringRetryApplication {

  public static void main(String[] args) {
    SpringApplication.run(SpringRetryApplication.class, args);
  }

}

配置重试策略

使用@Retryable注解标记需要重试的方法,

package guru.springframework;

import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;

public interface RetryService {

    @Retryable(  
        // 发生CustomRetryException 或 NullPointerException 异常时进行重试
        value = {CustomRetryException.class,NullPointerException.class},
        
        // 最大重试次数
        maxAttempts = 3,
        
        // 重试间隔的初始延迟和延迟倍数
        backoff = @Backoff(delay = 1000, multiplier = 2),
        
        // 排除 IndexOutOfBoundsException 异常
        exclude = { IndexOutOfBoundsException.class }
    )
    public String retry() throws CustomRetryException;
}

降级处理

配置相应的重试策略,在多次重试失败后执行降级操作,避免一直等待不确定的恢复时间

import org.springframework.retry.annotation.Recover;  

@Slf4j
@Service
public class RetryServiceImpl implements RetryService {

    // 表明callThirdApi是异步的
    @Async
    @Override
    public String retry() throws CustomRetryException {
        log.info("Throwing CustomRetryException in method retry");
        throw new CustomRetryException("Throw custom exception");
    }

    /**
    ** 当callThirdApi方法的重试次数达到上限时,执行此方法
    **/
    @Recover
    public String recover(Throwable throwable) {
        log.info("Default Retry servive test");
        return "Error Class :: " + throwable.getClass().getName();
    }
}

Hystrix

GitHUb

通过添加延迟容忍和容错逻辑来帮助您控制这些分布式服务之间的交互。Hystrix 通过隔离服务之间的访问点、阻止服务之间的级联故障并提供回退选项来实现此目的,所有这些都可以提高系统的整体弹性

使用熔断机制

添加依赖

<!-- Hystrix的依赖 -->
<dependency>  
    <groupId>org.springframework.cloud</groupId>  
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>  
</dependency>

配置启用Hystrix

在Spring Boot的主类上添加@EnableHystrix注解

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

使用Hystrix实现熔断

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;  
  
@Service  
public class HystrixTestService {  
    // 指定熔断时执行demoteHandler降级方法
    @HystrixCommand(fallbackMethod = "demoteHandler")  
    public String callThirdApi() {  
        // 调用第三方API的逻辑  
    }  
  
    public String demoteHandler() {  
        // 熔断时的降级逻辑  
    }  
}

参考: 1.mp.weixin.qq.com/s/JfeGkWxpo…

  1. www.baeldung.com/spring-retr…

  2. springframework.guru/retry-in-sp…