【发布时间】:2021-12-12 23:21:05
【问题描述】:
我可以在日志中看到 Spring retry 正在向远程服务器发送 2 个请求,并且两个请求都返回成功的响应。
我不知道背后的原因。
代码:
Class StatusClient{
@CircuitBreaker(maxAttemptsExpression = "#{${remote.broadridge.circuitBreaker.maxAttempts}}",
openTimeoutExpression = "#{${remote.broadridge.circuitBreaker.openTimeout}}", resetTimeoutExpression = "#{${remote.broadridge.circuitBreaker.resetTimeout}}")
public Optional<JobStatusResponseDTO> getStatus(String account, String jobNumber) {
client.post()
.uri(PATH)
.body(BodyInserters.fromValue(request))
.exchangeToMono(response -> {
if (response.statusCode() == HttpStatus.NO_CONTENT) {
return Mono.empty();
} else if (isClientOrServerError(response)) {
return Mono.error(new RemoteClientException(String.format("status is not received: %s", response.statusCode())));
}
stopWatch.stop();
log.info("time taken by the getStatus=[{}] for {}", (stopWatch.getTotalTimeMillis()), request);
return response.bodyToMono(JobStatusResponseDTO.class);
})
.block();
return Optional.ofNullable(block);}
}
Class status{
@Retryable(maxAttemptsExpression = "#{${remote.retry.maxAttempts}}", backoff = @Backoff(delayExpression = "#{${remote.retry.delay}}"))
public Optional<JobStatusResponseDTO> getStatus(String jobNumber, String accountNumber) {
return statusClient.getStatus(accountNumber, jobNumber);
}
}
application.yml 中的配置
circuitBreaker:
maxAttempts: 3 # defalut 3
openTimeout: 5000 # defalut 5000
resetTimeout: 20000 # defalut 20000
retry:
maxAttempts: 3 # defalut 3
delay: 1000 # defalut 1000
日志:
792 <14>1 2021-10-26T16:26:32.978917+00:00 - 2021-10-26 16:26:32.978 INFO [batch,ec40b8fe1f6a4cfb,06052e092b3f8e66] : time taken by the getStatus=[582] for JobStatusRequestDTO(account=12
456, jobNumber=S123456)
792 <14>1 2021-10-26T16:26:18.263121+00:00 2021-10-26 16:26:18.262 INFO [batch,ec40b8fe1f6a4cfb,21202725a0002bde] : time taken by the getStatus=[592] for JobStatusRequestDTO(account=12
456, jobNumber=S123456)
两个请求相隔几秒钟。
编辑 1: 将断路器更改为最大尝试为 1。现在它正在重试 3 次。还有一个问题。似乎它只调用远程服务器一次而不是之后调用。 远程调用被封装在一个断路器中。
第一次尝试日志:
status is not received: 503 SERVICE_UNAVAILABLE
第二次尝试日志:
org.springframework.retry.ExhaustedRetryException: Retry exhausted after last attempt with no recovery path;
第三次尝试日志:
org.springframework.retry.ExhaustedRetryException: Retry exhausted after last attempt with no recovery path;
circuitBreaker:
maxAttempts: 1
openTimeout: 5000 # defalut 5000
resetTimeout: 20000 # defalut 20000
retry:
maxAttempts: 3 # defalut 3
delay: 1000 # defalut 1000
【问题讨论】:
-
我刚刚对其进行了测试,它按预期工作;我建议您在
getStatus中打印堆栈跟踪,以查看每次调用它的位置。 -
@GaryRussell 是的,它只重试了 3 次 bt 存在问题。请参阅编辑 1。
标签: java spring spring-retry circuit-breaker