【问题标题】:Spring Retry: NeverRetryLogic Not working as I expected with ExceptionClassifierRetryPolicy春季重试:NeverRetryLogic 无法按预期使用 ExceptionClassifierRetryPolicy
【发布时间】:2017-05-23 14:17:51
【问题描述】:

我正在重试场景中工作(与 http 出站网关相关)。重试逻辑运行良好,但我的不重试逻辑看起来有错误。

如果我收到不同于 404,500,503,504 的 http 状态错误,我想做的是不重试。

为了对其进行测试,我有一个可配置的端点,我可以将其配置为在成功之前响应任何 http 状态错误 X 次。

例如,我可以将我的端点配置为在我第一次点击它时获得 http 400 状态,然后当我重试时,我会得到一个成功的响应。

也就是说,我所期望的是,当我第一次将端点配置为获得 http 400 状态时,永远不会重试,但看起来这不起作用。

我对永不重试场景的逻辑是这样的:

   <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;
    }

}

根据NeverRetryPolicy 类,它应该这样做:

允许第一次尝试但从不允许重试的 RetryPolicy。 也可用作其他策略的基类,例如用于测试 用作存根。

所以我的理解是,第一次尝试是当我们到达端点时,我们会收到 http 400 错误状态,然后永远不会重试。

这有什么问题?

【问题讨论】:

  • 你从哪里打电话给handleHttpErrorCode?而且,你对结果做了什么?在运行时选择策略看起来很奇怪,但我可能会错过更大的图景。编辑问题以添加调用代码和重试模板设置。
  • @GaryRussell 问题已更新。

标签: java spring spring-integration spring-retry


【解决方案1】:

您总是返回默认策略;看起来你需要一个return 这里...

return handleHttpErrorCode(statusCode);

顺便说一句,最好只创建一次策略,而不是每次都创建一个新策略。

【讨论】:

  • 你是对的! , 另外代码最后不应返回defaultRetry。取而代之的是,它应该返回neverRetry(),这样,我可以确保如果我得到与HttpStatusCodeException不同的东西,我不会重试
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多