0

我有一个在 Tomcat 服务器中运行的 Web 应用程序,它执行对外部服务器的调用。现在,我想使用 Resilience4j来限制TimeLimiter响应的等待时间,另外还想Bulkhead限制对外部服务器的并行调用量。

我不需要对外部系统的异步调用,因为 Tomcat 线程必须等待响应或超时,无论如何。

在这种情况下结合 theTimeLimiter和 the的最佳方法是什么?Bulkhead我需要 aSemaphoreBulkhead还是 theThreadPoolBulkhead以及如何将我的外部系统调用包装在 aFuture所需的a 中TimeLimiter

4

1 回答 1

3

您不能将 SemaphoreBulkhead 和 TimeLimiter 结合使用,因为如果 TimeLimiter 正在运行同一线程,则它无法停止任务的执行。

因此,您只能组合 TimeLimiter 和 ThreadPoolBulkhead。但只有当你想要一个非阻塞/异步代码而不阻塞你的线程时才有意义。

如果你想阻塞代码,你可以使用:

CompletableFuture.supplyAsync(() -> service.method()).get(1, TimeUnit.SECONDS);

如果您想要非阻塞代码并且可以使用 Java9 或更高版本,您可以这样做:

CompletableFuture.supplyAsync(() -> service.method()).orTimeout(1, TimeUnit.SECONDS);

orTimeout运算符可与 Resilience4j TimeLimiter 相媲美。

如果您必须使用 Java8 并想使用 Resilience4j,那么请执行

ThreadPoolBulkhead bulkhead = ThreadPoolBulkhead.ofDefaults("sample");
TimeLimiter timeLimiter = TimeLimiter.of(Duration.ofSeconds(1));

ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(3);
CompletableFuture<String> future = timeLimiter
    .executeCompletionStage(scheduler, 
        bulkhead.decorateSupplier(() -> service.method())).toCompletableFuture();

TimeLimiter 允许使用您自己的 ScheduledExecutorService,而 neworTimeout运算符则不允许。

我建议阅读这篇博文-> http://iteratrlearning.com/java9/2016/09/13/java9-timeouts-completablefutures.html

于 2020-01-30T14:29:39.577 回答