当前位置: 首页 > 知识库问答 >
问题:

Spring重试:NeverRetryLogic与ExceptionClassifierRetryPolicy不一样

宦砚
2023-03-14

我在一个重试场景中工作(与http出站网关相关)。重试逻辑工作得很好,但是我的不重试逻辑看起来有一个bug。

也就是说,我期望的是,当我第一次配置endpoint以获得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;
    }

}

共有1个答案

郝哲茂
2023-03-14

您总是返回默认策略;这里似乎需要返回...

return handleHttpErrorCode(statusCode);

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

 类似资料:
  • 本文向大家介绍Spring Cloud重试机制与各组件的重试总结,包括了Spring Cloud重试机制与各组件的重试总结的使用技巧和注意事项,需要的朋友参考一下 SpringCloud重试机制配置 首先声明一点,这里的重试并不是报错以后的重试,而是负载均衡客户端发现远程请求实例不可到达后,去重试其他实例。 feign重试机制 feign默认是通过自己包下的Retryer进行重试配置,默认是5次

  • 当我运行单元测试时,我希望thisFails()方法重试3次,然后我希望看到recovery logger行打印出来,但它只尝试一次,然后抛出异常。底部的输出是在我运行测试之后。 我错过了什么? 请忽略此部分,然后跳到代码。门楣匠认为我没有足够的说明来张贴。我认为这样的措辞足以让我的问题被人理解,但出于某种原因,我不允许发布这个问题,除非我写更多的东西。还有更多的东西,等等。 --Spring启动

  • 我是Spring的新手,尝试用一个简单的测试实现Spring重试。但是我不能让它工作,希望有人能告诉我我做错了什么。我还想知道,是否可以编写单元测试来验证Spring重试已经尝试了请求的最大重试次数?因为到目前为止,谷歌搜索似乎只能在集成测试中工作,因为它需要Spring首先设置上下文。

  • 因此,基本上,我只是尝试将数组中可被3整除的元素添加100并打印出数组。我不明白的是,当我在函数中使用时,它会打印出满足条件的数组,即100被添加到可被3整除的元素中,但当我在函数之外使用它时,它不会。为什么会这样?并且有没有一种方法可以在函数外打印出满足条件的测试数组?我刚刚开始学习javascript,所以我有点初学者。

  • 有人能解释这两种不同行为的原因并建议我重新尝试的最佳方法吗?(我使用的是JPA数据)

  • 我得堆栈: 想法2019.1.3 Springboot 2.1.6 Java 11 Maven 3.8.0 Groovy 2.5 史巴克1.3 JUnit jupiter 5.5.1 JUnit vintage 5.5.1 GMavenPlus插件2.7.1 我们想开始在Spock测试框架中编写测试。我跟着这个howto,但没有成功。当我尝试运行所有测试时,我的spock测试没有运行。 我能运行一