0
# Circuit Breaker Strategies
1
2
Circuit breaker patterns that prevent cascading failures by monitoring failure rates and temporarily blocking calls to failing services. Provides automatic failure detection, recovery mechanisms, and named circuit breaker instances for shared state.
3
4
## Capabilities
5
6
### Basic Circuit Breaker
7
8
Standard circuit breaker functionality with configurable failure thresholds, delays, and recovery logic.
9
10
```java { .api }
11
@CircuitBreaker(
12
requestVolumeThreshold = 20,
13
failureRatio = 0.5,
14
delay = 5000,
15
delayUnit = ChronoUnit.MILLISECONDS,
16
successThreshold = 1,
17
failOn = {IOException.class, TimeoutException.class},
18
skipOn = {IllegalArgumentException.class}
19
)
20
public ReturnType protectedMethod() throws Exception;
21
```
22
23
#### Parameters
24
25
- `requestVolumeThreshold` - Minimum requests before failure evaluation (default: 20)
26
- `failureRatio` - Failure ratio to open circuit (0.0-1.0, default: 0.5)
27
- `delay` - Time before transitioning from open to half-open (default: 5 seconds)
28
- `delayUnit` - Time unit for delay (default: MILLIS)
29
- `successThreshold` - Successful calls needed to close from half-open (default: 1)
30
- `failOn` - Exception types considered failures (default: Throwable.class)
31
- `skipOn` - Exception types not considered failures (takes precedence)
32
33
#### Circuit Breaker States
34
35
- **Closed**: Normal operation, calls pass through
36
- **Open**: Calls immediately fail without execution
37
- **Half-Open**: Test calls allowed to check service recovery
38
39
#### Usage Example
40
41
```java
42
@ApplicationScoped
43
public class PaymentService {
44
45
// Payment processing with circuit breaker
46
@CircuitBreaker(
47
requestVolumeThreshold = 10,
48
failureRatio = 0.3,
49
delay = 30000,
50
successThreshold = 3
51
)
52
@Fallback(fallbackMethod = "processPaymentOffline")
53
public PaymentResult processPayment(PaymentRequest request) throws PaymentException {
54
return paymentGateway.process(request);
55
}
56
57
public PaymentResult processPaymentOffline(PaymentRequest request) {
58
// Queue payment for later processing
59
return paymentQueue.enqueue(request);
60
}
61
62
// External service with aggressive circuit breaker
63
@CircuitBreaker(
64
requestVolumeThreshold = 5,
65
failureRatio = 0.2,
66
delay = 60000,
67
failOn = {ConnectException.class, SocketTimeoutException.class},
68
skipOn = {ValidationException.class}
69
)
70
public ExternalApiResponse callExternalService(ApiRequest request) {
71
return externalApiClient.call(request);
72
}
73
}
74
```
75
76
### Named Circuit Breakers
77
78
Named circuit breaker instances that share state across multiple methods or classes.
79
80
```java { .api }
81
@CircuitBreakerName("shared-circuit-breaker")
82
@CircuitBreaker(requestVolumeThreshold = 10, failureRatio = 0.4)
83
public ReturnType namedCircuitBreakerMethod();
84
85
// Multiple methods sharing the same circuit breaker state
86
@CircuitBreakerName("database-circuit")
87
public ReturnType firstDatabaseMethod();
88
89
@CircuitBreakerName("database-circuit")
90
public ReturnType secondDatabaseMethod();
91
```
92
93
#### Usage Example
94
95
```java
96
@ApplicationScoped
97
public class DatabaseService {
98
99
// All database operations share the same circuit breaker
100
@CircuitBreakerName("database-operations")
101
@CircuitBreaker(requestVolumeThreshold = 15, failureRatio = 0.3)
102
public List<User> findUsers(UserQuery query) throws SQLException {
103
return userRepository.find(query);
104
}
105
106
@CircuitBreakerName("database-operations")
107
@CircuitBreaker(requestVolumeThreshold = 15, failureRatio = 0.3)
108
public void saveUser(User user) throws SQLException {
109
userRepository.save(user);
110
}
111
112
@CircuitBreakerName("database-operations")
113
@CircuitBreaker(requestVolumeThreshold = 15, failureRatio = 0.3)
114
public void deleteUser(Long userId) throws SQLException {
115
userRepository.delete(userId);
116
}
117
}
118
119
@ApplicationScoped
120
public class OrderService {
121
122
// Order service also uses the same database circuit breaker
123
@CircuitBreakerName("database-operations")
124
@CircuitBreaker(requestVolumeThreshold = 15, failureRatio = 0.3)
125
public List<Order> findOrders(OrderQuery query) throws SQLException {
126
return orderRepository.find(query);
127
}
128
}
129
```
130
131
### Circuit Breaker with Fallback
132
133
Combined circuit breaker and fallback patterns for complete resilience.
134
135
```java { .api }
136
@CircuitBreaker(requestVolumeThreshold = 10, failureRatio = 0.5)
137
@Fallback(fallbackMethod = "fallbackMethod")
138
public ReturnType protectedMethodWithFallback();
139
140
@CircuitBreaker(requestVolumeThreshold = 5)
141
@Fallback(value = CustomFallbackHandler.class)
142
public ReturnType protectedMethodWithHandler();
143
```
144
145
#### Usage Example
146
147
```java
148
@ApplicationScoped
149
public class WeatherService {
150
151
@Inject
152
CacheService cache;
153
154
// Weather API with circuit breaker and cached fallback
155
@CircuitBreaker(
156
requestVolumeThreshold = 8,
157
failureRatio = 0.4,
158
delay = 20000
159
)
160
@Fallback(fallbackMethod = "getCachedWeather")
161
@Timeout(5000)
162
public WeatherData getCurrentWeather(String city) throws WeatherServiceException {
163
return weatherApiClient.getWeather(city);
164
}
165
166
public WeatherData getCachedWeather(String city) {
167
WeatherData cached = cache.get("weather:" + city);
168
if (cached != null) {
169
return cached.withStaleIndicator();
170
}
171
return WeatherData.unavailable(city);
172
}
173
174
// Stock quote service with handler-based fallback
175
@CircuitBreaker(requestVolumeThreshold = 5, failureRatio = 0.6)
176
@Fallback(value = StockQuoteFallbackHandler.class)
177
public StockQuote getStockQuote(String symbol) throws QuoteServiceException {
178
return stockApiClient.getQuote(symbol);
179
}
180
}
181
182
public class StockQuoteFallbackHandler implements FallbackHandler<StockQuote> {
183
184
@Inject
185
HistoricalDataService historicalData;
186
187
@Override
188
public StockQuote handle(ExecutionContext context) {
189
String symbol = (String) context.getParameters()[0];
190
// Return last known quote or estimated quote
191
return historicalData.getLastKnownQuote(symbol)
192
.orElse(StockQuote.estimated(symbol));
193
}
194
}
195
```
196
197
### Circuit Breaker Monitoring
198
199
Integration with metrics and health checks for circuit breaker monitoring.
200
201
```java { .api }
202
// Circuit breaker with custom name for monitoring
203
@CircuitBreakerName("payment-gateway")
204
@CircuitBreaker(requestVolumeThreshold = 20, failureRatio = 0.25)
205
public PaymentResult processPayment(PaymentRequest request);
206
207
// Accessing circuit breaker state programmatically
208
CircuitBreakerRegistry registry;
209
CircuitBreaker circuitBreaker = registry.circuitBreaker("payment-gateway");
210
CircuitBreaker.State state = circuitBreaker.getState();
211
```
212
213
#### Usage Example
214
215
```java
216
@ApplicationScoped
217
public class SystemHealthService {
218
219
@Inject
220
CircuitBreakerRegistry circuitBreakerRegistry;
221
222
@Inject
223
MeterRegistry meterRegistry;
224
225
public HealthCheckResponse checkCircuitBreakerHealth() {
226
List<String> openCircuits = new ArrayList<>();
227
228
// Check all named circuit breakers
229
for (String name : circuitBreakerRegistry.getAllCircuitBreakerNames()) {
230
CircuitBreaker cb = circuitBreakerRegistry.circuitBreaker(name);
231
if (cb.getState() == CircuitBreaker.State.OPEN) {
232
openCircuits.add(name);
233
}
234
}
235
236
if (openCircuits.isEmpty()) {
237
return HealthCheckResponse.up("circuit-breakers")
238
.withData("status", "All circuit breakers closed")
239
.build();
240
} else {
241
return HealthCheckResponse.down("circuit-breakers")
242
.withData("open-circuits", openCircuits)
243
.build();
244
}
245
}
246
247
@EventObserver
248
public void onCircuitBreakerStateChange(CircuitBreakerStateChangeEvent event) {
249
// Record metrics when circuit breaker state changes
250
Counter counter = Counter.builder("circuit.breaker.state.changes")
251
.tag("name", event.getCircuitBreakerName())
252
.tag("from", event.getFromState().toString())
253
.tag("to", event.getToState().toString())
254
.register(meterRegistry);
255
256
counter.increment();
257
}
258
}
259
```
260
261
### Advanced Circuit Breaker Patterns
262
263
Complex patterns combining circuit breakers with other fault tolerance strategies.
264
265
#### Retry with Circuit Breaker
266
267
```java { .api }
268
@Retry(maxRetries = 3, delay = 1000)
269
@CircuitBreaker(requestVolumeThreshold = 10, failureRatio = 0.5)
270
@Timeout(5000)
271
public ReturnType resilientMethod();
272
```
273
274
#### Bulkhead with Circuit Breaker
275
276
```java { .api }
277
@Bulkhead(value = 5, waitingTaskQueue = 10)
278
@CircuitBreaker(requestVolumeThreshold = 15, failureRatio = 0.4)
279
public ReturnType isolatedMethod();
280
```
281
282
#### Usage Example
283
284
```java
285
@ApplicationScoped
286
public class CriticalService {
287
288
// Maximum resilience combination
289
@Retry(maxRetries = 2, delay = 500)
290
@CircuitBreaker(
291
requestVolumeThreshold = 12,
292
failureRatio = 0.3,
293
delay = 45000
294
)
295
@Timeout(8000)
296
@Fallback(fallbackMethod = "criticalFallback")
297
@Bulkhead(value = 3)
298
public CriticalData performCriticalOperation(String operationId) throws Exception {
299
return criticalSystemClient.execute(operationId);
300
}
301
302
public CriticalData criticalFallback(String operationId) {
303
// Emergency fallback - might return cached data or trigger manual process
304
return emergencyDataSource.getCriticalData(operationId);
305
}
306
}
307
```
308
309
## Types
310
311
### Circuit Breaker Core Types
312
313
```java { .api }
314
// Circuit breaker states
315
enum CircuitBreakerState {
316
CLOSED, // Normal operation
317
OPEN, // Calls blocked
318
HALF_OPEN // Testing recovery
319
}
320
321
// Circuit breaker registry for programmatic access
322
interface CircuitBreakerRegistry {
323
CircuitBreaker circuitBreaker(String name);
324
Set<String> getAllCircuitBreakerNames();
325
}
326
327
// Circuit breaker instance
328
interface CircuitBreaker {
329
State getState();
330
Metrics getMetrics();
331
String getName();
332
333
enum State {
334
CLOSED, OPEN, HALF_OPEN, DISABLED, FORCED_OPEN
335
}
336
}
337
```
338
339
### Circuit Breaker Metrics
340
341
```java { .api }
342
// Circuit breaker metrics
343
interface CircuitBreakerMetrics {
344
int getNumberOfSuccessfulCalls();
345
int getNumberOfFailedCalls();
346
int getNumberOfBufferedCalls();
347
int getNumberOfSlowCalls();
348
float getFailureRate();
349
float getSlowCallRate();
350
Duration getSlowCallRateThreshold();
351
}
352
```
353
354
### Event Types
355
356
```java { .api }
357
// Circuit breaker events for monitoring
358
interface CircuitBreakerEvent {
359
String getCircuitBreakerName();
360
ZonedDateTime getCreationTime();
361
362
enum Type {
363
SUCCESS, ERROR, IGNORED_ERROR, STATE_TRANSITION,
364
RESET, DISABLED, FORCED_OPEN_STATE
365
}
366
}
367
368
// State change event
369
interface CircuitBreakerStateChangeEvent extends CircuitBreakerEvent {
370
CircuitBreaker.State getFromState();
371
CircuitBreaker.State getToState();
372
}
373
```