Spring Retry 是Spring框架中的一个组件, 它提供了失败调用方法,自动重新调用功能
org.springframework.retry
spring-retry
1.2.5.RELEASE
org.springframework
spring-aspects
5.2.8.RELEASE
@EnableRetry
@EnableAspectJAutoProxy(exposeProxy = true)
@SpringBootApplication
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication .class, args);
}
}
@Retryable(value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 2000L, multiplier = 1.5))
public void test() throws Exception{
//todo 方法体
}
注释属性解释:
注解的属性
interceptor:方法拦截器的名称
include:当抛出指定的异常时,才会重试。默认为空,为空时表示抛出任何异常都会重试
value:作用同include
exclude:指定被忽略的异常,当抛出指定异常时,不会重试
maxAttempts:最大重试次数,默认3次
backoff: 重试等待策略,默认使用@Backoff,@Backoff默认的delay值为1000L,即1秒后重试;multiplier默认为0,若设为1.5,则表示下一次重试等待的时间为上一次的1.5倍
补偿机制:如果retryServiceWithRecovery
方法在三次尝试之后还是抛出了SQLException
,那么recover()
方法将被调用
@Service
public interface MyService {
@Retryable(value = SQLException.class)
void retryServiceWithRecovery(String sql) throws SQLException;
@Recover
void recover(SQLException e, String sql);
}
2.1 使用配置文件 springRetry.properties
retry.maxAttempts=2
retry.maxDelay=100
2.2 @Configuration 加载配置文件
@Data
@PropertySource("classpath:retryConfig.properties")
@ConfigurationProperties(prefix = "retry")
@Configuration
public class SpringRetryConfig {
private Integer maxAttempts;
private Integer maxDelay;
}
2.3 现在使用的是maxAttemptsExpression
和delayExpression
而不是maxAttempts
和delay
@Service
public interface TestService {
@Retryable( value = SQLException.class, maxAttemptsExpression = "${retry.maxAttempts}",
backoff = @Backoff(delayExpression = "${retry.maxDelay}"))
void retryServiceWithExternalizedConfiguration(String sql) throws SQLException;
}
RetryTemplate
@Data
@PropertySource("classpath:retryConfig.properties")
@ConfigurationProperties(prefix = "retry")
@Configuration
public class SpringRetryConfig {
private Integer maxAttempts;
private Integer maxDelay;
@Bean
public RetryTemplate retryTemplate() {
RetryTemplate retryTemplate = new RetryTemplate();
SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
retryPolicy.setMaxAttempts(3);
FixedBackOffPolicy fixedBackOffPolicy = new FixedBackOffPolicy();
fixedBackOffPolicy.setBackOffPeriod(2000L);
retryTemplate.setRetryPolicy(retryPolicy);
retryTemplate.setBackOffPolicy(fixedBackOffPolicy);
return retryTemplate;
}
}
retryTemplate.execute(new RetryCallback() {
@Override
public Void doWithRetry(RetryContext arg0) {
testService.testRetryService();
...
}
});
//lambda
retryTemplate.execute(arg0 -> {
testService.testRetryService();
return null;
});