multithreading - 如何重复调用不可靠的 API?Completable Future 会比编写在线程中运行的标准 try catch 块有用吗?
问题描述
我必须一次通过网络多次调用关键 API(这使得它不可靠),一天多次。如果 API 无法响应(超时)或返回错误(因为该服务器又在调用其他不可靠的第三方),我必须通知他们该错误,然后再次调用原始 API。
在这里,错误通知也可能失败,我将不得不重试通知错误,直到我成功。之后我可以再次调用原始 API。
我想使用 CompletableFuture 来构建它。对于这种代码,它是一个正确的库选择吗?或者我应该在 Runnable 中的无限循环中放置一个 try catch 循环并执行它?CompletableFuture 会过分吗?还有其他选择吗?
解决方案
坦率地说,这个问题太宽泛了,因为答案真的取决于你已经在使用什么框架。问题是 - 今天有许多流行的框架提供开箱即用的重试逻辑实现。
例如:
如果您通过 feign 调用“关键 API”,则内置支持 retry。
如果您使用的是 Spring 的
RestTemplate
,那么您也可以使用Spring Retry如果您只需要简单的重试实用程序,则有许多库,例如故障安全和guava-retrying
但是,如果在考虑替代方案后您决定使用 手动重试CompletableFuture
,您绝对可以这样做。
例如,这里有一些简单的重试实用程序:
- 不限次数:
public static <T> CompletableFuture<T> retry(Throwable throwable, Function<Throwable, T> operation) {
return CompletableFuture.supplyAsync(() -> operation.apply(throwable))
.thenApply(CompletableFuture::completedFuture)
.exceptionally(error -> retry(error, operation))
.thenCompose(Function.identity());
}
注意:这里我假设,您可以根据Throwable
. 因此,operation
将错误作为输入并产生一些有用的结果作为输出。在您的情况下,错误 - 可能是critical API
调用错误,或者notification error
有用的结果 - 成功critical API
的结果。
- 固定次数(
MAX_RETRIES
在这种情况下):
public static <T> CompletableFuture<T> retry(Throwable throwable, Function<Throwable, T> operation, int retry) {
if (retry == MAX_RETRIES) return failedFuture(throwable);
return CompletableFuture.supplyAsync(() -> operation.apply(throwable))
.thenApply(CompletableFuture::completedFuture)
.exceptionally(error -> retry(error, operation, retry + 1))
.thenCompose(Function.identity());
}
public static <T> CompletableFuture<T> failedFuture(Throwable throwable) {
final CompletableFuture<T> failedFuture = new CompletableFuture<>();
failedFuture.completeExceptionally(throwable);
return failedFuture;
}
推荐阅读
- java - 如何将 ServletOutputStream 打印为字符串?
- tcp - Cisco Packet Tracer 中的 TCP 连接中断试验
- django - Django 错误:“模型尚未加载。”
- flutter - 如何在 Flutter 中更改背景图像的位置和旋转
- entity-framework-core - 如何从视图中获取数据并将其发送到控制器操作?ASP.NET 核心 MVC
- php - 无法连接到远程mysql
- maven - IntelliJ 引入 maven-enforcer-plugin 而不是 pom.xml 的明确一部分
- python - Keras:基于 Faster-RCNN 预测生成目标值
- mysql - 无法增加 openshift 部署模板中的副本数
- javascript - ReactStrap:显示在表格内的 LONG 下拉菜单存在问题