【问题标题】:Jodah Failsafe Library Timeout is taking longer then expectedJodah Failsafe Library Timeout 花费的时间比预期的要长
【发布时间】:2023-03-22 04:00:01
【问题描述】:

我有一种情况,我想实现 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 和接收 TimeoutExceededException 之间有 20 秒的延迟,这应该是 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);

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

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

【问题讨论】:

    标签: java spring exception timeout java-failsafe


    【解决方案1】:

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

    【讨论】:

    • 感谢@whiskeysierra。让我完整阅读,了解
    • 关于如何进行的任何建议。
    • 注册一个自定义调度器或使用默认调度器。然后切换到getAsync而不是get。这应该会给你想要的行为。
    猜你喜欢
    • 2016-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-30
    • 1970-01-01
    • 2020-04-01
    • 1970-01-01
    相关资源
    最近更新 更多