【问题标题】:Is this how spring @Retryable supposed to work?这是spring @Retryable 应该如何工作的吗?
【发布时间】:2021-09-05 14:57:48
【问题描述】:

我最近添加了 spring @Retryable 来处理 502 错误,而不是来自目标服务器的适当响应。 (带改造2)。

以下只是伪代码,但原始代码以类似的方式处理异常。

class BadGatewayException : RuntimeException

@Retryable(include = [BadGatewayException::class])
class A {

    private fun handle(block: () -> Call<T>): T {
        try {
            val response = val response = block().execute()
           
            ...      
      
            if (response.code() == 502) {
                throw BadGatewayException("The server suffers temporary connection problems.")
            }
            ...
        } catch(e: Exception) {
            throw RuntimeException("a system error has occurred")
        }
    }

}

我预计@Retryable 不会重试,因为与 502 一起出现的BadGatewayException 将立即被包裹在RuntimeException 中,然后被抛出。但是,当它被测试时,它似乎遵循了这一步

  1. 尝试从改造请求中获得响应
  2. 502 发生
  3. BadGatewayException抛出
  4. 重试(默认为 3) - 这里 BadGatewayException 以某种方式被捕获
  5. RuntimeException抛出

关键是,@Retryable 应该以这种方式拦截任何异常吗?还是我在这里遗漏了什么?

【问题讨论】:

    标签: spring-boot retrofit2 spring-retry


    【解决方案1】:

    注解使用的SimpleRetryPolicy不遍历cause链寻找分类异常;仅将顶级异常与分类列表进行比较。

    您必须将自己的RetryInterceptor 与适当配置的RetryTemplate 和SimpleRetryPolicy 连接起来。

        /**
         * Create a builder for a stateless retry interceptor.
         * @return The interceptor builder.
         */
        public static StatelessRetryInterceptorBuilder stateless() {
            return new StatelessRetryInterceptorBuilder();
        }
    
    RetryInterceptorBuilder.stateless()
        .retryPolicy(new SimpleRetryPolicy(...))
        .build();
    

    见

        /**
         * Create a {@link SimpleRetryPolicy} with the specified number of retry attempts. If
         * traverseCauses is true, the exception causes will be traversed until a match or the
         * root cause is found. The default value indicates whether to retry or not for
         * exceptions (or super classes thereof) that are not found in the map.
         * @param maxAttempts the maximum number of attempts
         * @param retryableExceptions the map of exceptions that are retryable based on the
         * map value (true/false).
         * @param traverseCauses true to traverse the exception cause chain until a classified
         * exception is found or the root cause is reached.
         * @param defaultValue the default action.
         */
        public SimpleRetryPolicy(int maxAttempts, Map<Class<? extends Throwable>, Boolean> retryableExceptions,
                boolean traverseCauses, boolean defaultValue) {
    

    (defaultValue = true 和 Map.of(BadGatewayException.class, false))。

    在interceptor注解属性中设置拦截器的bean名称。

    【讨论】:

      猜你喜欢
      • 2012-08-03
      • 2017-06-18
      • 1970-01-01
      • 2022-10-21
      • 1970-01-01
      • 2021-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多