ExceptionClassifierRetryPolicy
注意:目前很多博客上面在policy.setExceptionClassifier里面new出对象,这个是一个特别大的问题,如果你进入源码里面看的话,每次retry的时候,都会从ExceptionClassifierRetryPolicy里面拿下一个应该使用的policy,会先从缓存map里面拿retryContext,而policy并没有重写equals和hashcode方法,拿不到会把ExceptionClassifierRetryPolicy返回的当作map的key放进去,value是一个新的retryContext,所以如果一直重试,那么这个map将会一直变大导致oom,并且,使用simpleRetry重试次数会失效。
下面是正确用法:
public static void main(String[] args) throws TimeoutException {
RetryTemplate retryTemplate = new RetryTemplate();
// 根据异常设置重试策略
ExceptionClassifierRetryPolicy policy = new ExceptionClassifierRetryPolicy();
final SimpleRetryPolicy simpleRetryPolicy = new SimpleRetryPolicy(10);
AlwaysRetryPolicy alwaysRetryPolicy = new AlwaysRetryPolicy();
policy.setExceptionClassifier(classifiable -> {
if(classifiable instanceof TimeoutException){
//如果是网络问题,一直重试
return alwaysRetryPolicy;
}
//重试次数
return simpleRetryPolicy;
});
retryTemplate.setRetryPolicy(policy);
//固定时间重试机制
FixedBackOffPolicy fixedBackOffPolicy = new FixedBackOffPolicy();
fixedBackOffPolicy.setBackOffPeriod(1000);
retryTemplate.setBackOffPolicy(fixedBackOffPolicy);
Object execute = retryTemplate.execute(retryContext -> {
if(retryContext.getRetryCount()%2==0){
throw new RuntimeException();
}
throw new TimeoutException();
}, retryContext -> {
System.out.println("retry fail "+retryContext.getRetryCount());
return null;
});
Object execute2 = retryTemplate.execute(retryContext -> {
throw new RuntimeException("222");
}, retryContext -> {
System.out.println("retry fail "+retryContext.getRetryCount());
return null;
});
}
错误示例
下面是错误的用法,可以测试一下:注意,下面的代码是错误的 :
public static void main(String[] args) throws TimeoutException {
RetryTemplate retryTemplate = new RetryTemplate();
// 根据异常设置重试策略
ExceptionClassifierRetryPolicy policy = new ExceptionClassifierRetryPolicy();
policy.setExceptionClassifier(classifiable -> {
if(classifiable instanceof TimeoutException){
//如果是网络问题,一直重试
return new AlwaysRetryPolicy();
}
//重试次数
return new SimpleRetryPolicy();
});
retryTemplate.setRetryPolicy(policy);
//固定时间重试机制
FixedBackOffPolicy fixedBackOffPolicy = new FixedBackOffPolicy();
fixedBackOffPolicy.setBackOffPeriod(1000);
retryTemplate.setBackOffPolicy(fixedBackOffPolicy);
Object execute = retryTemplate.execute(retryContext -> {
if(retryContext.getRetryCount()%2==0){
throw new RuntimeException();
}
throw new TimeoutException();
}, retryContext -> {
System.out.println("retry fail "+retryContext.getRetryCount());
return null;
});
Object execute2 = retryTemplate.execute(retryContext -> {
throw new RuntimeException("222");
}, retryContext -> {
System.out.println("retry fail "+retryContext.getRetryCount());
return null;
});
}