Bulkhead
For introduction, see How to Limit Concurrency.
Description
If a guarded method is called by too many callers concurrently, the excess attempts will fail with BulkheadException
.
If the gaurded method is @Asynchronous
or @AsynchronousNonBlocking
, excess attempts are first put into a queue.
The queued attempts are executed later.
When the queue becomes full, excess attempts are rejected with BulkheadException
.
Lifecycle
Bulkhead needs to maintain some state between invocations: the number of current executions and the queue of asynchronous executions.
This state is a singleton, irrespective of the lifecycle of the bean that uses the @Bulkhead
annotation.
More specifically, the bulkhead state is uniquely identified by the combination of the bean class (java.lang.Class
) and the method object (java.lang.reflect.Method
) representing the guarded method.
For example, if there’s a guarded method doWork
on a bean which is @RequestScoped
, each request will have its own instance of the bean, but all invocations of doWork
will share the same bulkhead state.
Configuration
There are 2 configuration options, corresponding to the 2 members of the @Bulkhead
annotation.
waitingTaskQueue
Type: int
Default: 10
The size of queue for excess attempts.
Only effective when the method is @Asynchronous
or @AsynchronousNonBlocking
.
See the Asynchronous Execution reference guide.
Metrics
Bulkhead exposes the following metrics:
Name |
|
Type |
|
Unit |
None |
Description |
The number of times the bulkhead logic was run. This is usually once per method call, but may be zero times if the circuit breaker or rate limit prevented execution or more than once if the method call was retried. |
Tags |
|
Name |
|
Type |
|
Unit |
None |
Description |
Number of currently running executions. |
Tags |
|
Name |
|
Type |
|
Unit |
None |
Description |
Number of executions currently waiting in the queue. |
Tags |
|
Notes |
Only added if the method is also |
Name |
|
Type |
|
Unit |
Nanoseconds |
Description |
Histogram of the time that method executions spent running. |
Tags |
|
Name |
|
Type |
|
Unit |
Nanoseconds |
Description |
Histogram of the time that method executions spent waiting in the queue. |
Tags |
|
Notes |
Only added if the method is also |
See the Metrics reference guide for general metrics information.
Interactions with Other Strategies
See How to Use Multiple Strategies for an overview of how fault tolerance strategies are nested.
If @Fallback
is used with @Bulkhead
, the fallback method or handler may be invoked if a BulkheadException
is thrown, depending on the fallback configuration.
If @Retry
is used with @Bulkhead
, each retry attempt is processed by the bulkhead as an independent invocation.
If BulkheadException
is thrown, the execution may be retried, depending on how retry is configured.
If @CircuitBreaker
is used with @Bulkhead
, the circuit breaker is checked before enforcing the concurrency limit.
If concurrency limiting results in BulkheadException
, this may be counted as a failure, depending on how the circuit breaker is configured.
If @RateLimit
is used with @Bulkhead
, the rate limit is enforced before enforcing the concurrency limit.
If @Timeout
is used with @Bulkhead
, the timeout watcher is started before enforcing the concurrency limit.