1、SpringBoot2.7.8+SpringCloud2021.0.4+SpringCloudAlibaba2021.0.4.0 , Use OpenFeign + Resilience4J + Bulkhead to achieve a fuse and downgrade
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId>
</dependency>
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-bulkhead</artifactId>
</dependency>
2、I was trying to setup a sample with resilience4j semaphore bulkhead support with maxConcurrentCalls set as 10.
resilience4j.bulkhead:
instances:
backendA:
maxConcurrentCalls: 10
resilience4j:
circuitbreaker:
configs:
default:
slidingWindowSize: 10
slidingWindowType: TIME_BASED
failureRateThreshold: 50
minimumNumberOfCalls: 5
waitDurationInOpenState: 10s
writablestacktraceEnabled: false
3、Resilience4j Bulkhead setting Semaphorebulkhead mode
spring:
cloud:
circuitbreaker:
resilience4j:
enableSemaphoreDefaultBulkhead: true
4、Openfeign server simulation error
@GetMapping(path = "health")
public String health() {
try {
int i = 1/0;
} catch (Exception e) {
System.out.println("111");
throw new RuntimeException("111");
}
return "ok";
}
5、openfeign client
@EcsFeignClient(name = "console", url = "http://127.0.0.1:8095")
public interface TestFeign {
@GetMapping("health")
String health();
}
6、After the service melting, remote calls can still be generated, accessing remote services
executing in thread : ForkJoinPool.commonPool-worker-1
executing in thread : ForkJoinPool.commonPool-worker-2
exception io.github.resilience4j.bulkhead.BulkheadFullException: Bulkhead 'TestFeignhealthz' is full and does not permit further calls
7、On debugging Resilience4jBulkheadProvider, found that CompletableFuture asyncCall = CompletableFuture.supplyAsync(supplier); started a forkjoinpool thread and backend code execution was initiated even before the semaphore check was done.
I was under the impression that the backend code will be called only if semaphore check was succeeded.
org.springframework.cloud.circuitbreaker.resilience4j.Resilience4jBulkheadProvider#decorateBulkhead
private <T> Supplier<CompletionStage<T>> decorateBulkhead(final String id,
final io.vavr.collection.Map<String, String> tags, final Supplier<T> supplier) {
Resilience4jBulkheadConfigurationBuilder.BulkheadConfiguration configuration = configurations
.computeIfAbsent(id, defaultConfiguration);
if (semaphoreDefaultBulkhead
|| (bulkheadRegistry.find(id).isPresent() && !threadPoolBulkheadRegistry.find(id).isPresent())) {
Bulkhead bulkhead = bulkheadRegistry.bulkhead(id, configuration.getBulkheadConfig(), tags);
CompletableFuture<T> asyncCall = CompletableFuture.supplyAsync(supplier);
return Bulkhead.decorateCompletionStage(bulkhead, () -> asyncCall);
}
else {
ThreadPoolBulkhead threadPoolBulkhead = threadPoolBulkheadRegistry.bulkhead(id,
configuration.getThreadPoolBulkheadConfig(), tags);
return threadPoolBulkhead.decorateSupplier(supplier);
}
}
1、SpringBoot2.7.8+SpringCloud2021.0.4+SpringCloudAlibaba2021.0.4.0 , Use OpenFeign + Resilience4J + Bulkhead to achieve a fuse and downgrade
2、I was trying to setup a sample with resilience4j semaphore bulkhead support with maxConcurrentCalls set as 10.
3、Resilience4j Bulkhead setting Semaphorebulkhead mode
4、Openfeign server simulation error
5、openfeign client
6、After the service melting, remote calls can still be generated, accessing remote services
7、On debugging Resilience4jBulkheadProvider, found that CompletableFuture asyncCall = CompletableFuture.supplyAsync(supplier); started a forkjoinpool thread and backend code execution was initiated even before the semaphore check was done.
I was under the impression that the backend code will be called only if semaphore check was succeeded.
org.springframework.cloud.circuitbreaker.resilience4j.Resilience4jBulkheadProvider#decorateBulkhead