我有一个运行在Tomcat服务器上的web应用程序,它执行对外部服务器的调用。现在,我想使用Resilience4j的TimeLimiter来限制响应的等待时间,并另外使用一个Bulkhead来限制对外部服务器的并行调用的数量。
我不需要对外部系统的异步调用,因为Tomcat线程无论如何都必须等待响应或超时。
在此场景中,组合TimeLimiter和Bulkhead的最佳方式是什么?我是否需要SemaphoreBulkhead或ThreadPoolBulkhead?如何将外部系统调用包装在TimeLimiter所需的Future中
发布于 2020-01-30 22:29:40
您不能将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,而新的orTimeout操作符不允许。
我建议阅读这篇博文-> http://iteratrlearning.com/java9/2016/09/13/java9-timeouts-completablefutures.html
https://stackoverflow.com/questions/59823886
复制相似问题