Circuit Breaker
The Circuit Breaker pattern is inspired by the real-world electrical circuit breaker, which is used to detect excessive current draw and fail fast to protect electrical equipment. The software-based circuit breaker works on the same notion, by encapsulating the operation and monitoring it for failures. The Circuit Breaker pattern operates in three states, as illustrated in the following figure:
The states are as follows:
-
Closed: When operating successfully.
-
Open: When failure is detected, and the breaker opens to short-circuit and fails fast. In this state, the circuit breaker avoids invoking the protected operation and avoids putting the additional load on the struggling service.
-
Half-Open: After a short period in the open state, an operation is attempted to see whether it can complete successfully, and depending on the outcome, it will transfer to either open or closed state.
The Circuit Breaker eip supports the following options which are listed below.
| Name | Description | Default | Type |
|---|---|---|---|
note | The note for this node. | String | |
description | The description for this node. | String | |
disabled | Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime. | false | Boolean |
configuration | Refers to a circuit breaker configuration to use for configuring the circuit breaker EIP. | String | |
inheritErrorHandler | Whether to inherit Camel error handling during circuit breaker. By default, Camel error handler is turned off. | false | Boolean |
resilience4jConfiguration | Configures the circuit breaker to use Resilience4j with the given configuration. | Resilience4jConfigurationDefinition | |
faultToleranceConfiguration | Configures the circuit breaker to use MicroProfile Fault Tolerance with the given configuration. | FaultToleranceConfigurationDefinition | |
onFallback | The fallback route path to execute when the circuit breaker triggers. | OnFallbackDefinition | |
outputs | Required | List |
Exchange properties
The Circuit Breaker eip supports the following exchange properties which are listed below.
The exchange properties are set on the Exchange by the EIP, unless otherwise specified in the description. This means those properties are available after this EIP has completed processing the Exchange.
| Name | Description | Default | Type |
|---|---|---|---|
CamelResponseSuccessfulExecution | Whether the exchange was processed successfully by the circuit breaker. | boolean | |
CamelResponseFromFallback | Whether the exchange was processed by the onFallback by the circuit breaker. | boolean | |
CamelResponseShortCircuited | Whether the call did not complete normally and the circuit breaker short circuited the exchange, to the onFallback if there is one. This is true for a failed call, a timeout and a rejected call alike; use CamelCircuitBreakerResponseRejected to know whether the call was attempted. | boolean | |
CamelResponseTimedOut | Whether the exchange timed out during processing by the circuit breaker. | boolean | |
CamelResponseRejected | Whether the circuit breaker rejected the call without attempting it, because the breaker is open or the bulkhead is full. Also set inside the onFallback, where it tells a dead service apart from a single failed call. | boolean | |
CamelResponseIgnored | Whether the circuit breaker ignored an exception during processing. | boolean | |
CamelResponseState | The state of the circuit breaker. | String |
Inside the onFallback these properties tell why the fallback runs. CamelCircuitBreakerResponseFromFallback and CamelCircuitBreakerResponseShortCircuited are true whenever the fallback runs, whatever the cause. To know what happened to the call itself:
| What happened | CamelCircuitBreakerResponseRejected | CamelCircuitBreakerResponseTimedOut |
|---|---|---|
The call was made and failed |
| not set |
The call was made and timed out |
|
|
The call was not attempted: the breaker is open, or the bulkhead is full |
| not set |
CamelCircuitBreakerState is the state of the breaker after the call was recorded, so the call that opens the breaker reports OPEN although it was attempted; use the rejected property to know whether a call was made. The caught exception is available in the fallback, for example as ${exception.message} in the Simple language.
For example, a fallback that answers differently when the service is down rather than failing once:
- route:
from:
uri: timer:stock?period=1000
steps:
- circuitBreaker:
steps:
- to:
uri: direct:supplier
onFallback:
steps:
- choice:
when:
- expression:
simple:
expression: "${exchangeProperty.CamelCircuitBreakerResponseRejected} == true"
steps:
- setBody:
expression:
constant:
expression: "supplier is down, using the last known stock"
otherwise:
steps:
- setBody:
expression:
constant:
expression: "stock check failed, will try again" Example
Below is an example route showing a circuit breaker endpoint that protects against slow operation by falling back to the in-lined fallback route.
In this example, the circuit breaker protects against slow operation by falling back to the in-lined fallback route.
-
Java
-
XML
-
YAML
from("direct:start")
.circuitBreaker()
.to("http://fooservice.com/slow")
.onFallback()
.transform().constant("Fallback message")
.end()
.to("mock:result"); <route>
<from uri="direct:start"/>
<circuitBreaker>
<to uri="http://fooservice.com/slow"/>
<onFallback>
<transform>
<constant>Fallback message</constant>
</transform>
</onFallback>
</circuitBreaker>
<to uri="mock:result"/>
</route> - route:
from:
uri: direct:start
steps:
- circuitBreaker:
steps:
- to:
uri: http://fooservice.com/slow
onFallback:
steps:
- transform:
expression:
constant:
expression: Fallback message
- to:
uri: mock:result Route lifecycle and breaker state
When a route is stopped and started, the circuit breaker state is reset (an OPEN breaker returns to CLOSED) and any collected metrics are cleared. This is by design — a route stop/start is a full lifecycle reset, equivalent to a fresh boot.
Circuit Breaker components
Camel provides two implementations of this pattern:
-
Resilience4j: Using the Resilience4j implementation
-
Fault Tolerance: Using the MicroProfile Fault Tolerance implementation