Java Spring重试:NeverRetryLogic在ExceptionClassifierRetryPolicy中未按预期工作
我正在一个重试场景中工作(与http出站网关相关)。重试逻辑运行得很好,但我不重试的逻辑似乎有一个bug 如果得到与404500503504不同的http状态错误,我希望不要重试 为了测试它,我有一个可配置的端点,我可以将其配置为在获得成功之前响应任意http状态错误X次 例如,我可以将我的端点配置为在我第一次点击它时获得http 400状态,然后,当我重试时,我将获得成功的响应 这就是说,我所期望的是,当我第一次配置我的端点以获得HTTP400状态时,永远不要重试,但这似乎不起作用 我对永不重试场景的逻辑如下:Java Spring重试:NeverRetryLogic在ExceptionClassifierRetryPolicy中未按预期工作,java,spring,spring-integration,spring-retry,Java,Spring,Spring Integration,Spring Retry,我正在一个重试场景中工作(与http出站网关相关)。重试逻辑运行得很好,但我不重试的逻辑似乎有一个bug 如果得到与404500503504不同的http状态错误,我希望不要重试 为了测试它,我有一个可配置的端点,我可以将其配置为在获得成功之前响应任意http状态错误X次 例如,我可以将我的端点配置为在我第一次点击它时获得http 400状态,然后,当我重试时,我将获得成功的响应 这就是说,我所期望的是,当我第一次配置我的端点以获得HTTP400状态时,永远不要重试,但这似乎不起作用 我对永不重
<int-http:outbound-gateway
header-mapper="httpHeaderMapper"
request-channel="some_request_channel"
url-expression="'http://some_url"
http-method="POST"
expected-response-type="java.lang.String"
charset="UTF-8"
reply-timeout="${com.property.value.from.db.for.time.out:5000}"
reply-channel="some_reply_channel">
<int-http:request-handler-advice-chain>
<bean class="org.springframework.integration.handler.advice.RequestHandlerRetryAdvice">
<property name="recoveryCallback">
<bean class="org.springframework.integration.handler.advice.ErrorMessageSendingRecoverer">
<constructor-arg ref="errorChannel" />
</bean>
</property>
<property name="retryTemplate" ref="retryTemplate" />
</bean>
</int-http:request-handler-advice-chain>
</int-http:outbound-gateway>
<bean id="retryTemplate" class="org.springframework.retry.support.RetryTemplate">
<property name="retryPolicy">
<bean class="com.whatever.CustomRetryPolicy">
<property name="maxAttempts" value="${com.property.value.from.db.for.retry.MaxAttemps:5}" />
</bean>
</property>
<property name="backOffPolicy">
<bean class="org.springframework.retry.backoff.ExponentialBackOffPolicy">
<property name="initialInterval" value="${com.property.value.from.db.for.backoffpolicy.initialInterval:1000}" />
<property name="multiplier" value="${com.property.value.from.db.for.backoffpolicy.initialInterval:6}" />
</bean>
</property>
</bean>
CustomRetryPolicy是这样的:
public class CustomRetryPolicy extends ExceptionClassifierRetryPolicy {
private String maxAttempts;
@PostConstruct
public void init() {
final RetryPolicy defaultRetry = defaultRetryPolicy();
this.setExceptionClassifier(new Classifier<Throwable, RetryPolicy>() {
@Override
public RetryPolicy classify(Throwable classifiable) {
Throwable exceptionCause = classifiable.getCause();
if (exceptionCause instanceof HttpStatusCodeException) {
int statusCode = ((HttpStatusCodeException) classifiable.getCause()).getStatusCode().value();
handleHttpErrorCode(statusCode);
}
return defaultRetry;
}
});
}
public void setMaxAttempts(String maxAttempts) {
this.maxAttempts = maxAttempts;
}
private RetryPolicy handleHttpErrorCode(int statusCode) {
RetryPolicy retryPolicy = null;
switch(statusCode) {
case 404 :
case 500 :
case 503 :
case 504 :
retryPolicy = defaultRetryPolicy();
break;
default :
retryPolicy = neverRetry();
break;
}
return retryPolicy;
}
private RetryPolicy neverRetry() {
return new NeverRetryPolicy();
}
private RetryPolicy defaultRetryPolicy() {
final SimpleRetryPolicy simpleRetryPolicy = new SimpleRetryPolicy();
simpleRetryPolicy.setMaxAttempts(5);
return simpleRetryPolicy;
}
}
公共类CustomRetryPolicy扩展ExceptionClassifierRetryPolicy{
私有字符串;
@施工后
公共void init(){
final RetryPolicy defaultRetry=defaultRetryPolicy();
this.setExceptionClassifier(新分类器(){
@凌驾
公共检索策略分类(可丢弃分类){
Throwable exceptionCause=classifiable.getCause();
if(HttpStatusCodeException的异常实例){
int statusCode=((HttpStatusCodeException)classifiable.getCause()).getStatusCode().value();
handleHttpErrorCode(状态代码);
}
返回defaultRetry;
}
});
}
public void setMaxAttempts(字符串maxAttempts){
this.maxAttempts=maxAttempts;
}
私有RetryPolicy handleHttpErrorCode(int状态码){
RetryPolicy RetryPolicy=null;
开关(状态代码){
案例404:
案例500:
案例503:
案例504:
retryPolicy=defaultRetryPolicy();
打破
违约:
retryPolicy=neverRetry();
打破
}
退货政策;
}
private RetryPolicy neverRetry(){
返回新的NeverRetryPolicy();
}
私有RetryPolicy defaultRetryPolicy(){
最终SimpleRetryPolicy SimpleRetryPolicy=新SimpleRetryPolicy();
简单策略。设置最大尝试次数(5次);
回归简单主义;
}
}
根据NeverRetryPolicy
类,它应该这样做:
允许首次尝试但不允许重试的RetryPolicy。
也可用作其他策略的基类,例如用于测试
作为存根的目的
所以我的理解是,第一次尝试是当我们到达端点时,我们收到http 400错误状态,然后再也不重试
这有什么问题?您总是返回默认策略;看起来你需要一个
返回
这里
return handleHttpErrorCode(statusCode);
顺便说一下,最好只创建一次策略,而不是每次都创建一个新策略。您总是返回默认策略;看起来你需要一个
返回
这里
return handleHttpErrorCode(statusCode);
顺便说一下,最好只创建一次策略,而不是每次都创建一个新策略。您从哪里调用
handleHttpErrorCode
?那么,你对结果做了什么?在运行时选择策略看起来很奇怪,但我可能忽略了更大的问题。编辑问题以添加调用代码和重试模板设置。@GaryRussell问题已更新。您从哪里调用handleHttpErrorCode
?那么,你对结果做了什么?在运行时选择策略看起来很奇怪,但我可能忽略了更大的问题。编辑问题以添加呼叫代码和重试模板设置。@GaryRussell问题已更新。你说得对,此外,代码不应在末尾返回defaultRetry
。相反,相反,它应该返回neverry()
,这样,如果我得到与HttpStatusCodeException
不同的内容,我可以确保不会重试,此外,代码不应在末尾返回defaultRetry
。相反,它应该返回neverry()
,这样,我可以确保如果我得到与HttpStatusCodeException不同的内容,我不会重试