尝试使用@Retryable排除exception – 导致抛出ExhaustedRetryException
我正在尝试在调用REST模板的方法上使用@Retryable
。 如果由于通信错误而返回错误,我想重试,否则我想在调用时抛出exception。
当ApiException发生时,我得到一个ExhaustedRetryException,并且没有找到足够的’recoverables’,即@Recover
方法,而不是被@Retryable抛出和忽略。
我以为我会看到如果只有可恢复的方法存在可能使它快乐并仍然按照希望执行。 没那么多。 它不是抛出exception,而是调用可恢复的方法。
@Retryable(exclude = ApiException include = ConnectionException, maxAttempts = 5, backoff = @Backoff(multiplier = 2.5d, maxDelay = 1000000L, delay = 150000L)) Object call(String domainUri, ParameterizedTypeReference type, Optional domain = Optional.empty(), HttpMethod httpMethod = HttpMethod.POST) throws RestClientException { RequestEntity request = apiRequestFactory.createRequest(domainUri, domain, httpMethod) log.info "************************** Request Entity **************************" log.info "${request.toString()}" ResponseEntity response try { response = restTemplate.exchange(request, type) log.info "************************** Response Entity **************************" log.info "${response.toString()}" } catch (HttpStatusCodeException | HttpMessageNotWritableException httpException) { String errorMessage String exceptionClass = httpException.class.name.concat("-") if(httpException instanceof HttpStatusCodeException) { log.info "************************** API Error **************************" log.error("API responded with errors: ${httpException.responseBodyAsString}") ApiError apiError = buildErrorResponse(httpException.responseBodyAsString) errorMessage = extractErrorMessage(apiError) if(isHttpCommunicationError(httpException.getStatusCode().value())) { throw new ConnectionException(exceptionClass.concat(errorMessage)) } } errorMessage = StringUtils.isBlank(errorMessage) ? exceptionClass.concat(httpException.message) : exceptionClass.concat(errorMessage) throw new ApiException(httpMethod, domainUri, errorMessage) } if (type.type == ResponseEntity) { response } else response.body } @Recover Object connectionException(ConnectionException connEx) { log.error("Retry failure - communicaiton error") throw new ConnectionException(connEx.class.name + " - " + connEx.message) }
任何见解将不胜感激。 这是错误还是操作员错误? 这是使用Spring Boot 1.3.6和Spring-Retry 1.1.3。
您的包含/排除语法看起来很糟糕 – 甚至不会编译。
我刚刚写了一个快速测试,如果你没有@Recover
方法,它的工作原理与预期完全相同……
package com.example; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.retry.annotation.EnableRetry; import org.springframework.retry.annotation.Retryable; @SpringBootApplication @EnableRetry public class So38601998Application { public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(So38601998Application.class, args); Foo bean = context.getBean(Foo.class); try { bean.out("foo"); } catch (Exception e) { System.out.println(e); } try { bean.out("bar"); } catch (Exception e) { System.out.println(e); } } @Bean public Foo foo() { return new Foo(); } public static class Foo { @Retryable(include = IllegalArgumentException.class, exclude = IllegalStateException.class, maxAttempts = 5) public void out(String foo) { System.out.println(foo); if (foo.equals("foo")) { throw new IllegalArgumentException(); } else { throw new IllegalStateException(); } } } }
结果:
foo foo foo foo foo java.lang.IllegalArgumentException bar java.lang.IllegalStateException
如果你只是添加
@Recover public void connectionException(IllegalArgumentException e) { System.out.println("Retry failure"); }
你得到
foo foo foo foo foo Retry failure bar org.springframework.retry.ExhaustedRetryException: Cannot locate recovery method; nested exception is java.lang.IllegalStateException
所以你需要一个全能的@Recover
方法……
@Recover public void connectionException(Exception e) throws Exception { System.out.println("Retry failure"); throw e; }
结果:
foo foo foo foo foo Retry failure bar Retry failure java.lang.IllegalStateException
- 如何在java中运行groovy脚本?
- 使用Java或Groovy为SQLite编写用户定义的SQL函数?
- 是否可以更好地替代Groovy for Java集成测试?
- Grails – 无法从Controller调用服务 – >总是得到“无法调用null对象上的方法错误”
- 在java 8中的groovy和闭包中的闭包(lambda表达式)?
- 将Java库添加到Netbeans Grails项目中
- 在运行时从Jar文件加载资源
- Jenkins管道和java.nio.file。*方法的问题
- Selenium UnreachableBrowserException – SoapUI中的“无法启动新会话”Groovy TestStep