【问题标题】:Can we handle nested exceptions using spring retry?我们可以使用弹簧重试处理嵌套异常吗?
【发布时间】:2020-01-07 05:23:01
【问题描述】:

我正在学习 Spring Retry,对其能力有以下疑问:

我有一个连接到第三方应用程序 API 的函数。预计这可能会引发不同的异常,例如超时或 IO 异常。我试图查看 Spring 的重试模板是否能够在“每次”出现时处理此类嵌套异常。例如,当我们将单个异常的 maxAttempts 设置为 3 时,即使在重试范围内,它也应该在每次出现时尝试 3 次。例如,在尝试 1 - 发生异常 1 并且下一次尝试(尝试 2)成功,但现在发生异常 2,基于 retryPolicy 它应该为异常 2 启动尝试 1。

这可能吗?

基于一个小型 POC,我看到即使两种类型都被抛出,它也只尝试了 3 次:

带有 retryTemplate 的控制器类:

         retryTemplate.execute(new RetryCallback<Customer, Exception>(){
             @Override
                public Customer doWithRetry(RetryContext arg0) throws Exception{
                System.out.println("count #"+arg0.getRetryCount());
                if(arg0.getRetryCount()>0) {
                    System.out.println("throwable getClass Canonical Name "+arg0.getLastThrowable().getClass().getCanonicalName());
                }

                return  customerService.getCustomerDetails(choice);
             }});

异常模拟类:

Random r = new Random();

            int i = r.nextInt();
            i+=1;

            System.out.println("value of i "+i);
            if(i%2==0) {
                throw new Exception1();
            }
            else {
                throw new Exception2();
            }

这里是日志:

count #0
in getCustomerDetails
value of i -1050226395
count #1
throwable getClass Canonical Name Exception1
in getCustomerDetails
value of i 824190506
count #2
throwable getClass Canonical Name Exception2
in getCustomerDetails
value of i 1210506150
Exception1

预期结果:每次出现异常尝试 3 次

实际结果:总共只尝试了 3 次。

下面是我的 RetryPolicy:ExceptionClassifierRetryPolicy 具有两种异常类型的 policyMap

public RetryTemplate retryTemplate() {

    RetryTemplate retryTemplate = new RetryTemplate();
    final SimpleRetryPolicy simpleRetryPolicy = new SimpleRetryPolicy();
    simpleRetryPolicy.setMaxAttempts(3);
    FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();
    backOffPolicy.setBackOffPeriod(1500);
    final Map<Class<? extends Throwable>, RetryPolicy> policyMap = new HashMap<>();
    policyMap.put(Exception1.class, simpleRetryPolicy);
    policyMap.put(Exception2.class, simpleRetryPolicy);
    final ExceptionClassifierRetryPolicy retryPolicy = new ExceptionClassifierRetryPolicy();
    retryPolicy.setPolicyMap(policyMap);
    retryTemplate.setBackOffPolicy(backOffPolicy);
    retryTemplate.setRetryPolicy(retryPolicy);
    return retryTemplate;
}

问题:

  1. 这种场景可以使用 Spring 重试吗?
  2. 如果是这样,在上述实现中需要改变什么?

请指导。

【问题讨论】:

    标签: spring-boot spring-retry


    【解决方案1】:

    您可以使用 ExceptionClassifierRetryPolicy,但请务必为每种异常类型分配不同的 SimpleRetryPolicy 实例:

    ExceptionClassifierRetryPolicy retryPolicy = new ExceptionClassifierRetryPolicy();
    Map<Class<? extends Throwable>, RetryPolicy> policyMap = new HashMap<>();
    
    policyMap.put(Exception1.class, new SimpleRetryPolicy(3));
    policyMap.put(Exception2.class, new SimpleRetryPolicy(3));
    
    retryPolicy.setPolicyMap(policyMap);
    retryTemplate.setRetryPolicy(retryPolicy);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-04-24
      • 1970-01-01
      • 2011-07-02
      • 2021-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多