Spring重试发送重复请求
Posted
技术标签:
【中文标题】Spring重试发送重复请求【英文标题】:Spring retry sending duplicate request 【发布时间】: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。
【参考方案1】:
这是因为您将默认的 retry.maxAttempts 设置为 3,延迟时间为 1000 毫秒。如果在提到的延迟时间内没有响应,Spring 将自动重试。因此,将 retry.maxAttemps 替换为 2 则不会给出多个响应。
您可以简单地在 application.properties 中粘贴以下行。
retry.maxAttempts=2
retry.maxDelay=100
另外,我建议你通过this。
【讨论】:
以上是关于Spring重试发送重复请求的主要内容,如果未能解决你的问题,请参考以下文章
FedEx Api:错误的请求错误,缺少或重复的参数。请修改您的请求,然后重试
求求你们了,别再重复造轮子了,一个 Spring 注解轻松搞定循环重试功能!