我正在使用 Resilience4j 进行大量测试并监控线程的行为。
我正在使用 spring-boot 2.2.5,resilience4j 1.4.0。Gatling(加载工具),visualvm(分析线程)
我意识到:
当我使用隔板类型 = SEMAPHORE.
我意识到异步执行将使用默认的 ExecutorService,在这种情况下,ForkJoinPool 和此配置将起作用:
maxConcurrentCalls, maxWaitDuration
如果您使用的是bulkhead type = THREADPOOL,上述配置将被忽略。
当我使用散装的 THREADPOOL 时,这些配置将起作用:
maxThreadPoolSize, coreThreadPoolSize, queueCapacity, keepAliveDuration
这些配置将被忽略:
maxConcurrentCalls, maxWaitDuration
我的代码:
@CircuitBreaker(name = MyServiceCommand.BEAN_NAME, fallbackMethod = "fallback")
@TimeLimiter(name = MyServiceCommand.BEAN_NAME)
@Bulkhead(name = MyServiceCommand.BEAN_NAME, type = Bulkhead.Type.THREADPOOL)
@Component
@AllArgsConstructor
@Slf4j
public class MyServiceCommand extends ResilienceAbstractCommand {
protected static final String BEAN_NAME = "MyService";
private SlowService slowService;
public CompletableFuture<String> perform() {
return CompletableFuture.completedFuture(slowService.get());
}
private CompletableFuture<String> fallback() {
return CompletableFuture.completedFuture("fallback");
}
}
配置:
resilience4j.circuitbreaker:
configs:
default:
failureRateThreshold: 40
waitDurationInOpenState: 20s
minimumNumberOfCalls: 5
slowCallRateThreshold: 30
slowCallDurationThreshold: 300s
instances:
MyService:
baseConfig: default
ignoreExceptions:
- com.hotmart.display.commons.exception.BusinessException
resilience4j.bulkhead:
configs:
default:
maxConcurrentCalls: 800
maxWaitDuration: 15000
instances:
MyService:
baseConfig: default
resilience4j.thread-pool-bulkhead:
configs:
default:
maxThreadPoolSize: 10
queueCapacity: 500
instances:
MyService:
baseConfig: default
resilience4j.timelimiter:
configs:
default:
timeoutDuration: 300s
cancelRunningFuture: true
instances:
MyService:
baseConfig: default
SlowService 对另一个应用程序进行慢速网络调用
我配置这些值只是为了测试,在生产中这些值会有所不同。
问题是:
1 - 我的应用程序是 I/O Bound,我希望当有很多请求(40/s)时,resilience4j 创建的线程池达到 maxThreadPoolSize 数量,但只创建了 3 个线程(cpu 核心数量 -1)我看到了仅创建:
隔板-MyService-1、隔板-MyService-2、隔板-MyService-3
问题是什么?
2 - 我做了这个配置:
maxThreadPoolSize: 1
coreThreadPoolSize: 1
queueCapacity: 2
keepAliveDuration: 3
我将 slowService 配置为 10 秒,太慢了。
我一次做了 3 个请求,系统的行为是这样的:
- 一次只处理1个,没关系,因为core和maxThread都是1。
- 请求被查询了,没问题,因为queueCapacity是2。
但是,我希望在队列中等待的请求只等待 3ms,因为是配置的时间。
如何限制线程在队列中等待的最长时间?
[编辑][更新] 我做了更多的测试并意识到:
当一个线程忙时,如果所有 coreThread 都忙,另一个到达的请求将启动一个新任务,直到到达 coreThread。
如果池到达 coreThread,每个新请求都会被放入队列,队列满后,新请求会创建新线程,直到达到 maxPoolThread。
关于 keepAliveDuration,线程将在空闲一段时间后终止。coreThreadSize 将处于空闲状态,只会终止多余的线程。
我所有的疑问都通过我的测试得到了解答。
现在我只想知道 THREADPOOL 和 SEMAPHORE 之间的不同行为?