import com.codecoord.util.PrintUtil;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.retry.RetryCallback;
import org.springframework.retry.RetryContext;
import org.springframework.retry.RetryListener;
import org.springframework.retry.backoff.ExponentialBackOffPolicy;
import org.springframework.retry.policy.SimpleRetryPolicy;
import org.springframework.retry.support.RetryTemplate;
@Configuration
public class RetryTemplateConfig {
@Bean
public RetryTemplate retryTemplate() {
RetryTemplate retryTemplate = new RetryTemplate();
/// 回退固定时间(秒)
// 指数回退(秒),第一次回退1s,第二次回退2s
ExponentialBackOffPolicy exponentialBackOffPolicy = new ExponentialBackOffPolicy();
exponentialBackOffPolicy.setInitialInterval(1000L);
exponentialBackOffPolicy.setMultiplier(2);
retryTemplate.setBackOffPolicy(exponentialBackOffPolicy);
// 重试策略
SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
retryPolicy.setMaxAttempts(5);
retryTemplate.setRetryPolicy(retryPolicy);
// 设置监听器,open和close分别在启动和结束时执行一次
RetryListener[] listeners = {
new RetryListener() {
@Override
public
PrintUtil.print(“open”);
return true;
}
@Override
public
Throwable throwable) {
PrintUtil.print(“close”);
}
@Override
public
Throwable throwable) {
PrintUtil.print(“onError”);
}
}
};
retryTemplate.setListeners(listeners);
return retryTemplate;
}
}
- 在controller中注入RetryTemplate使用,也可以是在service中
@RestController
public class SpringRetryController {
@Resource
private RetryTemplate retryTemplate;
private static int count = 0;
@RequestMapping("/retry")
public Object retry() {
try {
count = 0;
retryTemplate.execute((RetryCallback
// 业务代码
// …
// 模拟抛出异常
++count;
throw new RuntimeException(“抛出异常”);
});
} catch (RuntimeException e) {
System.out.println(“Exception”);
}
return "retry = " + count;
}
}
- 访问retry接口,然后观察日志输出
18:27:20.648 - http-nio-8888-exec-1 - open
18:27:20.649 - http-nio-8888-exec-1 - retryTemplate.execute执行
18:27:20.649 - http-nio-8888-exec-1 - onError
18:27:21.658 - http-nio-8888-exec-1 - retryTemplate.execute执行
18:27:21.658 - http-nio-8888-exec-1 - onError
18:27:23.670 - http-nio-8888-exec-1 - retryTemplate.execute执行
18:27:23.670 - http-nio-8888-exec-1 - onError
18:27:27.679 - http-nio-8888-exec-1 - retryTemplate.execute执行
18:27:27.679 - http-nio-8888-exec-1 - onError
18:27:35.681 - http-nio-8888-exec-1 - retryTemplate.execute执行
18:27:35.681 - http-nio-8888-exec-1 - onError
18:27:35.681 - http-nio-8888-exec-1 - close
三、EnableRetry
================================================================================
import org.springframework.retry.annotation.Retryable;
public interface RetryService {
@Retryable
void retryServiceCall();
}
import org.springframework.retry.annotation.EnableRetry;
import org.springframework.stereotype.Service;
@EnableRetry
@Service
public class RetryServiceImpl implements RetryService {
@Override
public void retryServiceCall() {
PrintUtil.print(“方法调用…”);
throw new RuntimeException(“手工异常”);
}
}
- controller中注入service
@RequestMapping("/retryAnnotation")
public Object retryAnnotation() {
retryService.retryServiceCall();
return “retryAnnotation”;
}
- 将会默认重试
18:46:48.721 - http-nio-8888-exec-1 - 方法调用…
18:46:49.724 - http-nio-8888-exec-1 - 方法调用…
18:46:50.730 - http-nio-8888-exec-1 - 方法调用…
java.lang.RuntimeException: 手工异常
四、Retryable
==============================================================================
-
用于需要重试的方法上的注解
-
有以下几个属性
-
Retryable注解参数
-
value:指定发生的异常进行重试
-
include:和value一样,默认空,当exclude也为空时,所有异常都重试
-
exclude:指定异常不重试,默认空,当include也为空时,所有异常都重试
-
maxAttemps:重试次数,默认3
-
backoff:重试补偿机制,默认没有
-
@Backoff 注解 重试补偿策略
-
不设置参数时,默认使用FixedBackOffPolicy(指定等待时间),重试等待1000ms
-
设置delay,使用FixedBackOffPolicy(指定等待设置delay和maxDealy时,重试等待在这两个值之间均态分布)
-
设置delay、maxDealy、multiplier,使用 ExponentialBackOffPolicy(指数级重试间隔的实现),multiplier即指定延迟倍数,比如delay=5000L,multiplier=2,则第一次重试为5秒,第二次为10秒,第三次为20秒
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@documented
public @interface Retryable {
String interceptor() default “”;
Class extends Throwable>[] value() default {};
Class extends Throwable>[] include() default {};
Class extends Throwable>[] exclude() default {};
String label() default “”;
boolean stateful() default false;
int maxAttempts() default 3;
String maxAttemptsexpression() default “”;
Backoff backoff() default @Backoff();
String exceptionexpression() default “”;
String[] listeners() default {};
}
- 在需要重试的方法上配置对应的重试次数、重试异常的异常类型、设置回退延迟时间、重试策略、方法监听名称
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@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;
}
@Component
public class PlatformClassService {
@Retryable(
// 重试异常的异常类型
value = {Exception.class},
// 最大重试次数
maxAttempts = 5,
// 设置回退延迟时间
backoff = @Backoff(delay = 500),
// 配置回调方法名称
listeners = “retryListener”
)
public void call() {
System.out.println(“call…”);
throw new RuntimeException(“手工异常”);
}
}
// 初始延迟2秒,然后之后验收1.5倍延迟重试,总重试次数4
@Retryable(value = {Exception.class}, maxAttempts = 4, backoff = @Backoff(delay = 2000L, multiplier = 1.5))
- 监听方法,在配置类中进行配置
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)