我有一种情况,我想实现 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));