0
# Clustering and Load Balancing
1
2
Apache Dubbo's clustering system provides fault tolerance, load balancing, and traffic management capabilities across multiple service providers. It includes various cluster strategies, load balancing algorithms, routing rules, and provider directory management.
3
4
## Capabilities
5
6
### Cluster Strategies
7
8
Cluster strategies define how to handle failures and distribute requests across multiple service providers.
9
10
```java { .api }
11
/**
12
* Cluster interface for fault tolerance strategies
13
*/
14
@SPI(FailoverCluster.NAME)
15
public interface Cluster {
16
/**
17
* Join multiple invokers into a cluster
18
* @param directory Provider directory
19
* @return Cluster invoker
20
* @throws RpcException if cluster creation fails
21
*/
22
<T> Invoker<T> join(Directory<T> directory) throws RpcException;
23
}
24
```
25
26
**Built-in Cluster Implementations:**
27
28
```java { .api }
29
/**
30
* Failover cluster - automatically failover to other providers when failure occurs
31
*/
32
public class FailoverCluster implements Cluster {
33
public static final String NAME = "failover";
34
}
35
36
/**
37
* Failfast cluster - fail immediately on first error
38
*/
39
public class FailfastCluster implements Cluster {
40
public static final String NAME = "failfast";
41
}
42
43
/**
44
* Failsafe cluster - ignore failures and return empty result
45
*/
46
public class FailsafeCluster implements Cluster {
47
public static final String NAME = "failsafe";
48
}
49
50
/**
51
* Failback cluster - retry failed requests in background
52
*/
53
public class FailbackCluster implements Cluster {
54
public static final String NAME = "failback";
55
}
56
57
/**
58
* Broadcast cluster - broadcast invocation to all providers
59
*/
60
public class BroadcastCluster implements Cluster {
61
public static final String NAME = "broadcast";
62
}
63
64
/**
65
* Forking cluster - parallel invocation, return first successful result
66
*/
67
public class ForkingCluster implements Cluster {
68
public static final String NAME = "forking";
69
}
70
71
/**
72
* Available cluster - call the first available provider
73
*/
74
public class AvailableCluster implements Cluster {
75
public static final String NAME = "available";
76
}
77
78
/**
79
* Mergeable cluster - merge results from multiple providers
80
*/
81
public class MergeableCluster implements Cluster {
82
public static final String NAME = "mergeable";
83
}
84
```
85
86
**Usage Examples:**
87
88
```java
89
// Configure cluster strategy in service reference
90
ReferenceConfig<GreeterService> reference = new ReferenceConfig<>();
91
reference.setInterface(GreeterService.class);
92
reference.setCluster("failover"); // Use failover strategy
93
reference.setRetries(2); // Retry 2 times on failure
94
95
// Or configure via URL parameters
96
reference.setUrl("dubbo://localhost:20880/GreeterService?cluster=failfast");
97
```
98
99
### Load Balancing
100
101
Load balancing algorithms distribute requests across available service providers.
102
103
```java { .api }
104
/**
105
* Load balance interface for selecting providers
106
*/
107
@SPI(RandomLoadBalance.NAME)
108
public interface LoadBalance {
109
/**
110
* Select one invoker from available providers
111
* @param invokers Available service providers
112
* @param url Service URL with parameters
113
* @param invocation RPC invocation context
114
* @return Selected invoker
115
* @throws RpcException if selection fails
116
*/
117
<T> Invoker<T> select(List<Invoker<T>> invokers, URL url, Invocation invocation)
118
throws RpcException;
119
}
120
```
121
122
**Built-in Load Balance Implementations:**
123
124
```java { .api }
125
/**
126
* Random load balance - select provider randomly
127
*/
128
public class RandomLoadBalance extends AbstractLoadBalance {
129
public static final String NAME = "random";
130
131
@Override
132
protected <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) {
133
// Implementation selects random provider
134
return invokers.get(ThreadLocalRandom.current().nextInt(invokers.size()));
135
}
136
}
137
138
/**
139
* Round robin load balance - weighted round-robin selection
140
*/
141
public class RoundRobinLoadBalance extends AbstractLoadBalance {
142
public static final String NAME = "roundrobin";
143
}
144
145
/**
146
* Least active load balance - select provider with least active requests
147
*/
148
public class LeastActiveLoadBalance extends AbstractLoadBalance {
149
public static final String NAME = "leastactive";
150
}
151
152
/**
153
* Shortest response load balance - select provider with shortest response time
154
*/
155
public class ShortestResponseLoadBalance extends AbstractLoadBalance {
156
public static final String NAME = "shortestresponse";
157
}
158
159
/**
160
* Consistent hash load balance - consistent hash ring selection
161
*/
162
public class ConsistentHashLoadBalance extends AbstractLoadBalance {
163
public static final String NAME = "consistenthash";
164
}
165
166
/**
167
* Adaptive load balance - select based on adaptive algorithm
168
*/
169
public class AdaptiveLoadBalance extends AbstractLoadBalance {
170
public static final String NAME = "adaptive";
171
}
172
```
173
174
**Usage Examples:**
175
176
```java
177
// Configure load balancing in service reference
178
ReferenceConfig<GreeterService> reference = new ReferenceConfig<>();
179
reference.setInterface(GreeterService.class);
180
reference.setLoadbalance("roundrobin"); // Use round-robin load balancing
181
182
// Configure per method
183
MethodConfig method = new MethodConfig();
184
method.setName("sayHello");
185
method.setLoadbalance("leastactive");
186
reference.setMethods(Arrays.asList(method));
187
188
// Configure consistent hash with specific hash arguments
189
reference.setUrl("dubbo://localhost:20880/GreeterService?loadbalance=consistenthash&hash.arguments=0");
190
```
191
192
### Provider Directory
193
194
Directory interface manages the list of available service providers and handles provider changes.
195
196
```java { .api }
197
/**
198
* Provider directory for managing service provider lists
199
* @param <T> Service interface type
200
*/
201
public interface Directory<T> {
202
/** Get service interface class */
203
Class<T> getInterface();
204
205
/**
206
* List available invokers for the invocation
207
* @param invocation RPC invocation context
208
* @return List of available invokers
209
* @throws RpcException if listing fails
210
*/
211
List<Invoker<T>> list(Invocation invocation) throws RpcException;
212
213
/** Get all invokers regardless of availability */
214
List<Invoker<T>> getAllInvokers();
215
216
/** Get directory URL */
217
URL getUrl();
218
219
/** Check if directory is destroyed */
220
boolean isDestroyed();
221
222
/** Destroy directory and release resources */
223
void destroy();
224
225
/** Get consumer URL */
226
URL getConsumerUrl();
227
}
228
229
/**
230
* Registry-aware directory that subscribes to provider changes
231
*/
232
public class RegistryDirectory<T> extends AbstractDirectory<T> implements NotifyListener {
233
public RegistryDirectory(Class<T> serviceType, URL url);
234
235
/** Subscribe to registry for provider updates */
236
public void subscribe(URL url);
237
238
/** Unsubscribe from registry */
239
public void unsubscribe(URL url);
240
241
/** Handle provider change notifications */
242
public void notify(List<URL> urls);
243
244
/** Refresh provider list */
245
protected void refreshInvoker(List<URL> invokerUrls);
246
}
247
248
/**
249
* Static directory with fixed provider list
250
*/
251
public class StaticDirectory<T> extends AbstractDirectory<T> {
252
public StaticDirectory(List<Invoker<T>> invokers);
253
public StaticDirectory(URL url, List<Invoker<T>> invokers);
254
}
255
```
256
257
### Router System
258
259
Routers filter and sort providers based on routing rules.
260
261
```java { .api }
262
/**
263
* Router interface for filtering and sorting providers
264
*/
265
@SPI
266
public interface Router extends Comparable<Router> {
267
/** Get router URL */
268
URL getUrl();
269
270
/**
271
* Route providers based on rules
272
* @param invokers Available providers
273
* @param url Consumer URL
274
* @param invocation RPC invocation
275
* @return Filtered providers
276
* @throws RpcException if routing fails
277
*/
278
<T> List<Invoker<T>> route(List<Invoker<T>> invokers, URL url, Invocation invocation)
279
throws RpcException;
280
281
/** Check if routing is required for this invocation */
282
boolean isRuntime();
283
284
/** Check if router should be forced to execute */
285
boolean isForce();
286
287
/** Get router priority (lower value = higher priority) */
288
int getPriority();
289
}
290
291
/**
292
* Router chain for managing multiple routers
293
*/
294
public class RouterChain<T> {
295
public RouterChain(URL url);
296
297
/** Add router to chain */
298
public void addRouter(Router router);
299
300
/** Remove router from chain */
301
public void removeRouter(Router router);
302
303
/** Route through all routers in chain */
304
public List<Invoker<T>> route(URL url, Invocation invocation);
305
306
/** Set invokers for routing */
307
public void setInvokers(List<Invoker<T>> invokers);
308
}
309
```
310
311
**Built-in Router Types:**
312
313
```java { .api }
314
/**
315
* Condition router based on rules
316
*/
317
public class ConditionRouter implements Router {
318
public ConditionRouter(URL url);
319
320
/** Parse routing conditions */
321
protected void parseRule(String rule);
322
}
323
324
/**
325
* Script router using JavaScript expressions
326
*/
327
public class ScriptRouter implements Router {
328
public ScriptRouter(URL url);
329
}
330
331
/**
332
* File-based router loading rules from files
333
*/
334
public class FileRouter implements Router {
335
public FileRouter(URL url);
336
}
337
338
/**
339
* Tag router for routing based on request tags
340
*/
341
public class TagRouter implements Router {
342
public TagRouter(URL url);
343
}
344
```
345
346
**Usage Examples:**
347
348
```java
349
// Condition router rule examples
350
// Route requests with parameter "user" = "admin" to providers in group "admin"
351
String rule = "user = admin => group = admin";
352
353
// Route all requests during 9-17 hours to specific providers
354
String timeRule = "=> host = 192.168.1.10,192.168.1.11";
355
356
// Configure router in consumer
357
reference.setUrl("dubbo://localhost:20880/GreeterService?router=condition&rule=" +
358
URLEncoder.encode(rule, "UTF-8"));
359
```
360
361
### Configurator System
362
363
Configurators provide dynamic configuration changes for routing and load balancing.
364
365
```java { .api }
366
/**
367
* Configurator interface for dynamic configuration
368
*/
369
@SPI
370
public interface Configurator extends Comparable<Configurator> {
371
/** Get configurator URL */
372
URL getUrl();
373
374
/**
375
* Configure URL with dynamic rules
376
* @param url Original URL
377
* @return Configured URL
378
*/
379
URL configure(URL url);
380
}
381
382
/**
383
* Factory for creating configurators
384
*/
385
@SPI("override")
386
public interface ConfiguratorFactory {
387
/**
388
* Create configurator from URL
389
* @param url Configuration URL
390
* @return Configurator instance
391
*/
392
Configurator getConfigurator(URL url);
393
}
394
395
/**
396
* Override configurator for parameter overrides
397
*/
398
public class OverrideConfigurator implements Configurator {
399
public OverrideConfigurator(URL url);
400
401
@Override
402
public URL configure(URL url) {
403
// Apply parameter overrides
404
return url.addParameters(getUrl().getParameters());
405
}
406
}
407
408
/**
409
* Absent configurator for conditional configuration
410
*/
411
public class AbsentConfigurator implements Configurator {
412
public AbsentConfigurator(URL url);
413
}
414
```
415
416
### Cluster Invoker
417
418
Abstract base class for cluster invoker implementations.
419
420
```java { .api }
421
/**
422
* Abstract cluster invoker providing common cluster functionality
423
* @param <T> Service interface type
424
*/
425
public abstract class AbstractClusterInvoker<T> implements Invoker<T> {
426
protected AbstractClusterInvoker(Directory<T> directory);
427
protected AbstractClusterInvoker(Directory<T> directory, URL url);
428
429
/** Get provider directory */
430
public Directory<T> getDirectory();
431
432
/** Get cluster URL */
433
public URL getUrl();
434
435
/** Check if invoker is available */
436
public boolean isAvailable();
437
438
/** Destroy cluster invoker */
439
public void destroy();
440
441
/**
442
* List available invokers with load balancing
443
* @param invocation RPC invocation
444
* @param loadbalance Load balance algorithm
445
* @return Selected invoker
446
* @throws RpcException if no invoker available
447
*/
448
protected List<Invoker<T>> list(Invocation invocation) throws RpcException;
449
450
/**
451
* Select invoker using load balance
452
* @param loadbalance Load balance algorithm
453
* @param invocation RPC invocation
454
* @param invokers Available invokers
455
* @param selected Previously selected invokers (for retry)
456
* @return Selected invoker
457
*/
458
protected Invoker<T> select(LoadBalance loadbalance, Invocation invocation,
459
List<Invoker<T>> invokers, List<Invoker<T>> selected)
460
throws RpcException;
461
462
/**
463
* Template method for cluster-specific invocation
464
* @param invocation RPC invocation
465
* @return Invocation result
466
* @throws RpcException if invocation fails
467
*/
468
protected abstract Result doInvoke(Invocation invocation, List<Invoker<T>> invokers,
469
LoadBalance loadbalance) throws RpcException;
470
}
471
```
472
473
### Sticky Sessions
474
475
Configuration for sticky session support to ensure requests from the same client go to the same provider.
476
477
```java { .api }
478
/**
479
* Sticky session management for consistent provider selection
480
*/
481
public class StickyUtils {
482
/**
483
* Get sticky invoker for the invocation
484
* @param invokers Available invokers
485
* @param invocation Current invocation
486
* @param stickyInvoker Previously selected sticky invoker
487
* @return Sticky invoker if available and sticky
488
*/
489
public static <T> Invoker<T> getSticky(List<Invoker<T>> invokers,
490
Invocation invocation,
491
Invoker<T> stickyInvoker) {
492
// Return sticky invoker if still available and sticky is enabled
493
if (stickyInvoker != null && invokers.contains(stickyInvoker) &&
494
isSticky(invocation)) {
495
return stickyInvoker;
496
}
497
return null;
498
}
499
500
/** Check if sticky session is enabled for invocation */
501
private static boolean isSticky(Invocation invocation) {
502
String sticky = invocation.getAttachment(STICKY_KEY);
503
return "true".equals(sticky);
504
}
505
}
506
```
507
508
**Usage Examples:**
509
510
```java
511
// Enable sticky sessions in service reference
512
ReferenceConfig<GreeterService> reference = new ReferenceConfig<>();
513
reference.setInterface(GreeterService.class);
514
reference.setSticky(true); // Enable sticky sessions
515
516
// Configure sticky per method
517
MethodConfig method = new MethodConfig();
518
method.setName("sayHello");
519
method.setSticky(true);
520
reference.setMethods(Arrays.asList(method));
521
522
// Set sticky attachment manually
523
RpcContext.getContext().setAttachment("sticky", "true");
524
String result = greeterService.sayHello("World");
525
```
526
527
### Fault Tolerance
528
529
Configuration for fault tolerance behavior including timeouts, retries, and circuit breakers.
530
531
```java { .api }
532
/**
533
* Constants for fault tolerance configuration
534
*/
535
public class ClusterConstants {
536
/** Cluster fault tolerance strategy */
537
public static final String CLUSTER_KEY = "cluster";
538
539
/** Load balance algorithm */
540
public static final String LOADBALANCE_KEY = "loadbalance";
541
542
/** Sticky session */
543
public static final String STICKY_KEY = "sticky";
544
545
/** Retry times */
546
public static final String RETRIES_KEY = "retries";
547
548
/** Fail strategy */
549
public static final String FAIL_KEY = "fail";
550
551
/** Fork count for forking cluster */
552
public static final String FORKS_KEY = "forks";
553
554
/** Default retry times */
555
public static final int DEFAULT_RETRIES = 2;
556
557
/** Default fork count */
558
public static final int DEFAULT_FORKS = 2;
559
}
560
```
561
562
**Usage Examples:**
563
564
```java
565
// Configure comprehensive fault tolerance
566
ReferenceConfig<GreeterService> reference = new ReferenceConfig<>();
567
reference.setInterface(GreeterService.class);
568
reference.setCluster("failover"); // Automatic failover
569
reference.setLoadbalance("roundrobin"); // Round-robin load balancing
570
reference.setRetries(3); // Retry 3 times on failure
571
reference.setTimeout(5000); // 5 second timeout
572
reference.setConnections(5); // 5 connections per provider
573
574
// Method-specific fault tolerance
575
MethodConfig criticalMethod = new MethodConfig();
576
criticalMethod.setName("processOrder");
577
criticalMethod.setCluster("failfast"); // Fail immediately for critical operations
578
criticalMethod.setTimeout(10000); // Longer timeout for critical operations
579
criticalMethod.setRetries(0); // No retries for critical operations
580
581
reference.setMethods(Arrays.asList(criticalMethod));
582
```