【问题标题】:Spring retry sending duplicate requestSpring重试发送重复请求
【发布时间】: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


【解决方案1】:

这是因为您将默认的 retry.maxAttempts 设置为 3,延迟时间为 1000 毫秒。如果在提到的延迟时间内没有响应,Spring 将自动重试。因此,将 retry.maxAttemps 替换为 2 则不会给出多个响应。

您可以简单地在 application.properties 中粘贴以下行。

retry.maxAttempts=2
retry.maxDelay=100

另外,我建议你通过this

【讨论】:

    猜你喜欢
    • 2015-01-14
    • 2019-10-15
    • 2019-04-18
    • 1970-01-01
    • 2023-03-15
    • 2017-11-14
    • 2019-11-11
    • 1970-01-01
    • 2018-09-10
    相关资源
    最近更新 更多