I found that resilience4j creates a thread pool for every feign method. There are hundreds of feign method in my project. So resilience4j will create thousands of bulkhead thread.
org.springframework.cloud.circuitbreaker.resilience4j.Resilience4jBulkheadProvider(line 115)
private <T> Supplier<CompletionStage<T>> decorateBulkhead(final String id, final Supplier<T> supplier) {
// I would like id to be the name of @FeignClient
Resilience4jBulkheadConfigurationBuilder.BulkheadConfiguration configuration = configurations
.computeIfAbsent(id, defaultConfiguration);
if (bulkheadRegistry.find(id).isPresent() && !threadPoolBulkheadRegistry.find(id).isPresent()) {
Bulkhead bulkhead = bulkheadRegistry.bulkhead(id, configuration.getBulkheadConfig());
CompletableFuture<T> asyncCall = CompletableFuture.supplyAsync(supplier);
return Bulkhead.decorateCompletionStage(bulkhead, () -> asyncCall);
}
else {
ThreadPoolBulkhead threadPoolBulkhead = threadPoolBulkheadRegistry.bulkhead(id,
configuration.getThreadPoolBulkheadConfig());
return threadPoolBulkhead.decorateSupplier(supplier);
}
}
TimeLimiter creates newSingleThreadScheduledExecutor for every feign invoke. It may lead thread leaks.
org.springframework.cloud.circuitbreaker.resilience4j.Resilience4jBulkheadProvider(line 104)
Maybe bulkhead isn't the proper strategy for hundreds of feign methods and it should be moved to a different layer. Also see #113 for the option to default to semaphore.
spring-cloud-circuitbreaker-resilience4j-2.0.1
I found that resilience4j creates a thread pool for every feign method. There are hundreds of feign method in my project. So resilience4j will create thousands of bulkhead thread. org.springframework.cloud.circuitbreaker.resilience4j.Resilience4jBulkheadProvider(line 115)
TimeLimiter creates newSingleThreadScheduledExecutor for every feign invoke. It may lead thread leaks. org.springframework.cloud.circuitbreaker.resilience4j.Resilience4jBulkheadProvider(line 104)