1

我有一种情况,我想实现 API 重试机制。假设我有一个调用第三方 API 的 API,其中正常响应时间低于 2 秒,但有时我们收到一条错误消息,显示“服务不可用”、“网关超时”等。

所以我上网看看我们是否有一个图书馆来处理这些事情,我发现了https://jodah.net/failsafe/


使用库的目的:-

如果不到 5 秒,我没有得到结果,我将取消当前调用的执行并再试一次。

为此,在库中我可以看到我们有超时重试策略

首先我正在尝试超时。

 Timeout<Object> timeout = Timeout.of(Duration.ofMillis(1000)).withCancel(true)
        .onFailure(e -> logger.error("Connection attempt timed out {} {} ",new DateTime(), e.getFailure()))
        .onSuccess(e -> logger.info("Execution completed on time"));


       try {
         logger.info("TIme: {}", new DateTime());
         result = Failsafe.with(timeout).get(() -> restTemplate.postForEntity(messageSendServiceUrl, request, String.class));

      } catch (TimeoutExceededException | HttpClientErrorException e) {
        logger.info("TIme: {}", new DateTime());
        logger.error("Timeout exception", e);

      } catch (Exception e) {
        logger.error("Exception", e);
      }

但是在计算时间时,我在调用 API 和接收之间有 20 秒的延迟TimeoutExceededException,因为持续时间应该是 1 秒Duration.ofMillis(1000)。下面你可以看到 21 秒的差异。

TIme: 2020-06-11T10:00:17.964+05:30
Connection attempt timed out 2020-06-11T10:00:39.037+05:30 {}

你能告诉我我在这里做错了什么吗?

二是重试策略

RetryPolicy<Object> retryPolicy = new RetryPolicy<>()
    .handle(HttpClientErrorException.class, TimeoutExceededException.class, Exception.class)
    .withDelay(Duration.ofSeconds(1))
    .withMaxRetries(3);

我希望TimeoutExceededException在假设 3 秒后发生异常,延迟 1 秒,再次触发请求,最多重试 3 次。我用它作为

 result = Failsafe.with(retryPolicy,timeout).get(() -> restTemplate.postForEntity(messageSendServiceUrl, request, String.class));
4

1 回答 1

0

get是阻塞或同步操作,它使用调用线程。Failsafe 几乎没有办法提前停止。超时最好与异步操作结合使用,通常由*Async方法指示。确保你阅读了https://jodah.net/failsafe/schedulers/因为默认值有一些含义,并且对于 IO-bound 操作来说通常是一个糟糕的选择。

于 2020-06-16T06:45:55.413 回答