0
# Load Balancing
1
2
Advanced load balancing implementations that provide sophisticated traffic distribution, graceful policy switching, outlier detection, and multi-child load balancer patterns for gRPC services.
3
4
## Capabilities
5
6
### Graceful Switch Load Balancer
7
8
The `GracefulSwitchLoadBalancer` provides seamless switching between different load balancing policies without dropping connections.
9
10
```java { .api }
11
/**
12
* Load balancer that gracefully swaps to a new load balancing policy.
13
* Maintains connections during policy transitions by keeping the old policy
14
* active until the new policy is ready.
15
*/
16
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/5999")
17
@NotThreadSafe
18
public final class GracefulSwitchLoadBalancer extends ForwardingLoadBalancer {
19
20
/**
21
* Creates a new graceful switch load balancer
22
* @param helper the load balancer helper for creating subchannels and updating state
23
*/
24
public GracefulSwitchLoadBalancer(Helper helper);
25
26
/**
27
* Handles resolved addresses and potentially switches to a new load balancing policy
28
* @param resolvedAddresses the resolved addresses containing policy configuration
29
*/
30
@Override
31
public void handleResolvedAddresses(ResolvedAddresses resolvedAddresses);
32
33
/**
34
* Accepts resolved addresses and returns status
35
* @param resolvedAddresses the resolved addresses containing policy configuration
36
* @return Status indicating success or failure
37
*/
38
@Override
39
public Status acceptResolvedAddresses(ResolvedAddresses resolvedAddresses);
40
41
/**
42
* Shuts down both current and pending load balancers
43
*/
44
@Override
45
public void shutdown();
46
47
/**
48
* Gets the simple class name of the current delegate load balancer
49
* @return delegate type name for debugging
50
*/
51
public String delegateType();
52
53
/**
54
* Parses load balancing policy configuration from JSON
55
* @param loadBalancingConfigs list of load balancing configuration maps
56
* @return ConfigOrError containing parsed configuration or error
57
*/
58
public static ConfigOrError parseLoadBalancingPolicyConfig(List<Map<String, ?>> loadBalancingConfigs);
59
60
/**
61
* Parses load balancing policy configuration with custom registry
62
* @param loadBalancingConfigs list of load balancing configuration maps
63
* @param lbRegistry the load balancer registry to use for parsing
64
* @return ConfigOrError containing parsed configuration or error
65
*/
66
public static ConfigOrError parseLoadBalancingPolicyConfig(List<Map<String, ?>> loadBalancingConfigs, LoadBalancerRegistry lbRegistry);
67
68
/**
69
* Creates load balancing policy configuration directly
70
* @param childFactory the child load balancer factory
71
* @param childConfig the child load balancer configuration (may be null)
72
* @return configuration object for the graceful switch load balancer
73
*/
74
public static Object createLoadBalancingPolicyConfig(LoadBalancer.Factory childFactory, @Nullable Object childConfig);
75
}
76
```
77
78
**Configuration:**
79
80
```java { .api }
81
/**
82
* Configuration for graceful switch load balancer
83
*/
84
static final class Config {
85
final LoadBalancer.Factory childFactory;
86
@Nullable final Object childConfig;
87
88
public Config(LoadBalancer.Factory childFactory, @Nullable Object childConfig);
89
}
90
```
91
92
**Usage Examples:**
93
94
```java
95
import io.grpc.util.GracefulSwitchLoadBalancer;
96
import io.grpc.LoadBalancer;
97
import io.grpc.LoadBalancerRegistry;
98
99
// Create graceful switch load balancer
100
LoadBalancer.Helper helper = createHelper(); // Your helper implementation
101
GracefulSwitchLoadBalancer loadBalancer = new GracefulSwitchLoadBalancer(helper);
102
103
// Parse configuration from service config
104
List<Map<String, ?>> lbConfigs = Arrays.asList(
105
Map.of("round_robin", Map.of())
106
);
107
ConfigOrError configResult = GracefulSwitchLoadBalancer.parseLoadBalancingPolicyConfig(lbConfigs);
108
109
if (configResult.getError() == null) {
110
Object config = configResult.getConfig();
111
// Use config in resolved addresses
112
}
113
114
// Create configuration directly
115
LoadBalancer.Factory roundRobinFactory = LoadBalancerRegistry.getDefaultRegistry()
116
.getProvider("round_robin").newLoadBalancer(helper);
117
Object config = GracefulSwitchLoadBalancer.createLoadBalancingPolicyConfig(roundRobinFactory, null);
118
```
119
120
### Multi-Child Load Balancer
121
122
Base class for implementing load balancers that manage multiple child load balancers.
123
124
```java { .api }
125
/**
126
* Base class for load balancers that manage multiple child load balancers.
127
* Provides infrastructure for creating and managing child balancers with
128
* automatic state aggregation.
129
*/
130
@Internal
131
public abstract class MultiChildLoadBalancer extends LoadBalancer {
132
133
/**
134
* Creates a new multi-child load balancer
135
* @param helper the load balancer helper
136
*/
137
protected MultiChildLoadBalancer(Helper helper);
138
139
/**
140
* Updates the overall balancing state based on child states.
141
* Subclasses must implement this to define how child states are aggregated
142
* into the overall connectivity state and picker.
143
*/
144
protected abstract void updateOverallBalancingState();
145
146
/**
147
* Creates a mapping from keys to resolved addresses for child load balancers
148
* @param resolvedAddresses the resolved addresses from name resolution
149
* @return map of child keys to their respective resolved addresses
150
*/
151
protected Map<Object, ResolvedAddresses> createChildAddressesMap(ResolvedAddresses resolvedAddresses);
152
153
/**
154
* Creates a new child load balancer state
155
* @param key the unique key for this child
156
* @return new ChildLbState instance
157
*/
158
protected ChildLbState createChildLbState(Object key);
159
160
/**
161
* Aggregates connectivity states using standard gRPC rules
162
* @param overallState the current overall state
163
* @param childState the child state to aggregate
164
* @return the new aggregated state
165
*/
166
protected static ConnectivityState aggregateState(ConnectivityState overallState, ConnectivityState childState);
167
168
/**
169
* Gets the load balancer helper
170
* @return the helper instance
171
*/
172
protected Helper getHelper();
173
174
/**
175
* Gets the list of children in READY state
176
* @return list of ready child load balancer states
177
*/
178
protected List<ChildLbState> getReadyChildren();
179
180
/**
181
* Accepts resolved addresses and updates child load balancers
182
* @param resolvedAddresses the resolved addresses
183
* @return Status indicating success or failure
184
*/
185
@Override
186
public Status acceptResolvedAddresses(ResolvedAddresses resolvedAddresses);
187
188
/**
189
* Handles name resolution errors by forwarding to all children
190
* @param error the name resolution error
191
*/
192
@Override
193
public void handleNameResolutionError(Status error);
194
195
/**
196
* Shuts down all child load balancers
197
*/
198
@Override
199
public void shutdown();
200
201
/**
202
* Gets all child load balancer states for testing
203
* @return collection of child states
204
*/
205
@VisibleForTesting
206
public Collection<ChildLbState> getChildLbStates();
207
}
208
```
209
210
**Child Load Balancer State:**
211
212
```java { .api }
213
/**
214
* Represents the state of a child load balancer
215
*/
216
public class ChildLbState {
217
218
/**
219
* Creates a new child load balancer state
220
* @param key unique key for this child
221
* @param policyFactory factory for creating the child load balancer
222
*/
223
public ChildLbState(Object key, LoadBalancer.Factory policyFactory);
224
225
/**
226
* Gets the unique key for this child
227
* @return the child key
228
*/
229
public Object getKey();
230
231
/**
232
* Gets the child load balancer instance for testing
233
* @return the load balancer instance
234
*/
235
@VisibleForTesting
236
public LoadBalancer getLb();
237
238
/**
239
* Gets the current picker for testing
240
* @return the current subchannel picker
241
*/
242
@VisibleForTesting
243
public SubchannelPicker getCurrentPicker();
244
245
/**
246
* Gets the current connectivity state
247
* @return the current connectivity state
248
*/
249
public ConnectivityState getCurrentState();
250
251
/**
252
* Shuts down this child load balancer
253
*/
254
protected void shutdown();
255
256
/**
257
* Creates the helper for this child load balancer
258
* @return child-specific helper instance
259
*/
260
protected LoadBalancer.Helper createChildHelper();
261
262
/**
263
* Sets the current connectivity state
264
* @param currentState the new connectivity state
265
*/
266
protected void setCurrentState(ConnectivityState currentState);
267
268
/**
269
* Sets the current subchannel picker
270
* @param currentPicker the new picker
271
*/
272
protected void setCurrentPicker(SubchannelPicker currentPicker);
273
}
274
```
275
276
### Round Robin Load Balancer
277
278
Round-robin load balancer implementation that distributes requests evenly across available endpoints.
279
280
```java { .api }
281
/**
282
* Load balancer that distributes requests in round-robin fashion across
283
* all available subchannels.
284
*/
285
final class RoundRobinLoadBalancer extends MultiChildLoadBalancer {
286
287
/**
288
* Creates a new round-robin load balancer
289
* @param helper the load balancer helper
290
*/
291
public RoundRobinLoadBalancer(Helper helper);
292
293
/**
294
* Updates the overall balancing state with round-robin picker
295
*/
296
@Override
297
protected void updateOverallBalancingState();
298
299
/**
300
* Creates child load balancer state for round-robin
301
* @param key the child key
302
* @return new child state
303
*/
304
@Override
305
protected ChildLbState createChildLbState(Object key);
306
}
307
```
308
309
**Round Robin Picker:**
310
311
```java { .api }
312
/**
313
* Picker that selects subchannels in round-robin fashion
314
*/
315
@VisibleForTesting
316
public static final class ReadyPicker extends SubchannelPicker {
317
318
/**
319
* Creates a new round-robin picker
320
* @param list list of subchannel pickers to rotate through
321
* @param index atomic integer for tracking current position
322
*/
323
public ReadyPicker(List<SubchannelPicker> list, AtomicInteger index);
324
325
/**
326
* Picks a subchannel using round-robin algorithm
327
* @param args pick arguments
328
* @return pick result with selected subchannel
329
*/
330
@Override
331
public PickResult pickSubchannel(PickSubchannelArgs args);
332
333
/**
334
* Gets the list of subchannel pickers for testing
335
* @return list of pickers
336
*/
337
@VisibleForTesting
338
List<SubchannelPicker> getSubchannelPickers();
339
}
340
```
341
342
### Outlier Detection Load Balancer
343
344
Load balancer with outlier detection and ejection capabilities for improved fault tolerance.
345
346
```java { .api }
347
/**
348
* Load balancer that performs outlier detection and temporarily ejects
349
* poorly performing endpoints from the load balancing pool.
350
*/
351
@Internal
352
public final class OutlierDetectionLoadBalancer extends LoadBalancer {
353
354
/**
355
* Creates a new outlier detection load balancer
356
* @param helper the load balancer helper
357
* @param timeProvider provider for current time (for testing)
358
*/
359
public OutlierDetectionLoadBalancer(Helper helper, TimeProvider timeProvider);
360
361
/**
362
* Accepts resolved addresses with outlier detection configuration
363
* @param resolvedAddresses resolved addresses with configuration
364
* @return Status indicating success or failure
365
*/
366
@Override
367
public Status acceptResolvedAddresses(ResolvedAddresses resolvedAddresses);
368
369
/**
370
* Handles name resolution errors
371
* @param error the name resolution error
372
*/
373
@Override
374
public void handleNameResolutionError(Status error);
375
376
/**
377
* Shuts down the outlier detection load balancer
378
*/
379
@Override
380
public void shutdown();
381
}
382
```
383
384
**Outlier Detection Configuration:**
385
386
```java { .api }
387
/**
388
* Configuration for outlier detection load balancer
389
*/
390
public static class OutlierDetectionLoadBalancerConfig {
391
392
/**
393
* Builder for outlier detection configuration
394
*/
395
public static class Builder {
396
/**
397
* Sets the interval between outlier detection runs
398
* @param intervalNanos interval in nanoseconds
399
* @return builder for method chaining
400
*/
401
public Builder setIntervalNanos(Long intervalNanos);
402
403
/**
404
* Sets the base ejection time for outliers
405
* @param baseEjectionTimeNanos base ejection time in nanoseconds
406
* @return builder for method chaining
407
*/
408
public Builder setBaseEjectionTimeNanos(Long baseEjectionTimeNanos);
409
410
/**
411
* Sets the maximum ejection time for outliers
412
* @param maxEjectionTimeNanos maximum ejection time in nanoseconds
413
* @return builder for method chaining
414
*/
415
public Builder setMaxEjectionTimeNanos(Long maxEjectionTimeNanos);
416
417
/**
418
* Sets the maximum percentage of endpoints that can be ejected
419
* @param maxEjectionPercent maximum ejection percentage (0-100)
420
* @return builder for method chaining
421
*/
422
public Builder setMaxEjectionPercent(Integer maxEjectionPercent);
423
424
/**
425
* Sets success rate ejection configuration
426
* @param successRateEjection success rate ejection settings
427
* @return builder for method chaining
428
*/
429
public Builder setSuccessRateEjection(SuccessRateEjection successRateEjection);
430
431
/**
432
* Sets failure percentage ejection configuration
433
* @param failurePercentageEjection failure percentage ejection settings
434
* @return builder for method chaining
435
*/
436
public Builder setFailurePercentageEjection(FailurePercentageEjection failurePercentageEjection);
437
438
/**
439
* Sets the child load balancer configuration
440
* @param childConfig child load balancer configuration
441
* @return builder for method chaining
442
*/
443
public Builder setChildConfig(Object childConfig);
444
445
/**
446
* Builds the outlier detection configuration
447
* @return configured OutlierDetectionLoadBalancerConfig
448
*/
449
public OutlierDetectionLoadBalancerConfig build();
450
}
451
}
452
```
453
454
**Success Rate Ejection:**
455
456
```java { .api }
457
/**
458
* Configuration for success rate based outlier ejection
459
*/
460
public static class SuccessRateEjection {
461
462
/**
463
* Builder for success rate ejection configuration
464
*/
465
public static class Builder {
466
/**
467
* Sets the standard deviation factor for success rate ejection
468
* @param stdevFactor standard deviation factor
469
* @return builder for method chaining
470
*/
471
public Builder setStdevFactor(Integer stdevFactor);
472
473
/**
474
* Sets the enforcement percentage for success rate ejection
475
* @param enforcementPercentage enforcement percentage (0-100)
476
* @return builder for method chaining
477
*/
478
public Builder setEnforcementPercentage(Integer enforcementPercentage);
479
480
/**
481
* Sets the minimum number of hosts required for ejection
482
* @param minimumHosts minimum number of hosts
483
* @return builder for method chaining
484
*/
485
public Builder setMinimumHosts(Integer minimumHosts);
486
487
/**
488
* Sets the minimum request volume required for ejection
489
* @param requestVolume minimum request volume
490
* @return builder for method chaining
491
*/
492
public Builder setRequestVolume(Integer requestVolume);
493
494
/**
495
* Builds the success rate ejection configuration
496
* @return configured SuccessRateEjection
497
*/
498
public SuccessRateEjection build();
499
}
500
}
501
```
502
503
**Usage Examples:**
504
505
```java
506
import io.grpc.util.MultiChildLoadBalancer;
507
import io.grpc.util.RoundRobinLoadBalancer;
508
import io.grpc.util.OutlierDetectionLoadBalancer;
509
510
// Custom multi-child load balancer
511
public class CustomLoadBalancer extends MultiChildLoadBalancer {
512
513
public CustomLoadBalancer(Helper helper) {
514
super(helper);
515
}
516
517
@Override
518
protected void updateOverallBalancingState() {
519
List<ChildLbState> readyChildren = getReadyChildren();
520
if (readyChildren.isEmpty()) {
521
getHelper().updateBalancingState(
522
ConnectivityState.TRANSIENT_FAILURE,
523
new FixedResultPicker(PickResult.withNoResult())
524
);
525
} else {
526
// Custom picking logic
527
getHelper().updateBalancingState(
528
ConnectivityState.READY,
529
new CustomPicker(readyChildren)
530
);
531
}
532
}
533
}
534
535
// Round-robin load balancer usage
536
LoadBalancer.Helper helper = createHelper();
537
RoundRobinLoadBalancer rrLoadBalancer = new RoundRobinLoadBalancer(helper);
538
539
// Outlier detection configuration
540
OutlierDetectionLoadBalancer.OutlierDetectionLoadBalancerConfig config =
541
new OutlierDetectionLoadBalancer.OutlierDetectionLoadBalancerConfig.Builder()
542
.setIntervalNanos(Duration.ofSeconds(10).toNanos())
543
.setBaseEjectionTimeNanos(Duration.ofSeconds(30).toNanos())
544
.setMaxEjectionPercent(50)
545
.setSuccessRateEjection(
546
new OutlierDetectionLoadBalancer.SuccessRateEjection.Builder()
547
.setStdevFactor(1900) // 1.9 standard deviations
548
.setEnforcementPercentage(100)
549
.setMinimumHosts(5)
550
.setRequestVolume(100)
551
.build()
552
)
553
.build();
554
```
555
556
## Load Balancer Provider
557
558
Provider implementation for registering load balancers with the gRPC registry.
559
560
```java { .api }
561
/**
562
* Provider for outlier detection load balancer
563
*/
564
@Internal
565
public final class OutlierDetectionLoadBalancerProvider extends LoadBalancerProvider {
566
567
/**
568
* Creates a new outlier detection load balancer
569
* @param helper the load balancer helper
570
* @return new OutlierDetectionLoadBalancer instance
571
*/
572
@Override
573
public LoadBalancer newLoadBalancer(Helper helper);
574
575
/**
576
* Checks if the provider is available
577
* @return true if available
578
*/
579
@Override
580
public boolean isAvailable();
581
582
/**
583
* Gets the provider priority
584
* @return provider priority for selection
585
*/
586
@Override
587
public int getPriority();
588
589
/**
590
* Gets the load balancing policy name
591
* @return "outlier_detection_experimental"
592
*/
593
@Override
594
public String getPolicyName();
595
596
/**
597
* Parses load balancing policy configuration
598
* @param rawConfig raw configuration map
599
* @return ConfigOrError with parsed configuration or error
600
*/
601
@Override
602
public ConfigOrError parseLoadBalancingPolicyConfig(Map<String, ?> rawConfig);
603
}
604
```
605
606
## Types
607
608
```java { .api }
609
/**
610
* Endpoint wrapper for optimized address group lookup
611
*/
612
public static class Endpoint {
613
public Endpoint(EquivalentAddressGroup eag);
614
615
@Override
616
public int hashCode();
617
618
@Override
619
public boolean equals(Object obj);
620
621
@Override
622
public String toString();
623
}
624
```