#Dubbo 负载均衡策略
某电商平台的商品服务有 10 个实例,其中 2 个实例因为 GC 导致响应变慢(200ms),其他 8 个实例正常(5ms)。
使用默认的加权轮询负载均衡策略,2 个慢实例仍然被分配了相同的流量,导致整体 RT 飙高。
改用"最少活跃调用数"策略后,Dubbo 自动将流量分配到响应快的实例上,整体 RT 恢复正常。
【架构权衡】 负载均衡策略的选择直接影响系统的稳定性和响应时间。没有最好的策略,只有最适合业务的策略。响应时间稳定时用加权轮询,实例性能差异大时用最少活跃。
#一、核心问题 🔴
#1.1 六种负载均衡策略
| 策略 | 原理 | 适用场景 |
|---|---|---|
| Random | 随机选择 | 场景简单 |
| WeightedRandom | 加权随机 | 实例性能不同 |
| RoundRobin | 轮询 | 实例性能相同 |
| WeightedRoundRobin | 加权轮询 | 实例性能不同 |
| LeastActive | 最少活跃调用 | 响应时间差异大 |
| ConsistentHash | 一致性哈希 | 缓存友好 |
#1.2 策略实现原理
// RandomLoadBalance
public class RandomLoadBalance extends AbstractLoadBalance {
@Override
protected <T> T doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) {
int length = invokers.size();
boolean sameWeight = true;
int[] weights = new int[length];
int totalWeight = 0;
for (int i = 0; i < length; i++) {
int weight = getWeight(invokers.get(i), invocation);
totalWeight += weight;
weights[i] = totalWeight;
if (sameWeight && i > 0 && weight != weights[i - 1]) {
sameWeight = false;
}
}
if (totalWeight > 0 && !sameWeight) {
int offset = ThreadLocalRandom.current().nextInt(totalWeight);
for (int i = 0; i < length; i++) {
if (offset < weights[i]) {
return invokers.get(i);
}
}
}
return invokers.get(ThreadLocalRandom.current().nextInt(length));
}
}
// LeastActiveLoadBalance
public class LeastActiveLoadBalance extends AbstractLoadBalance {
@Override
protected <T> T doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) {
int length = invokers.size();
int leastActive = -1;
int leastCount = 0;
int[] leastIndexes = new int[length];
for (int i = 0; i < length; i++) {
Invoker<T> invoker = invokers.get(i);
int active = RpcStatus.getStatus(invoker.getUrl(), invocation.getMethodName())
.getActive();
if (active < leastActive || leastActive == -1) {
leastActive = active;
leastCount = 1;
leastIndexes[0] = i;
} else if (active == leastActive) {
leastIndexes[leastCount++] = i;
}
}
// 从最少活跃的实例中加权随机
if (leastCount == 1) {
return invokers.get(leastIndexes[0]);
}
// ...
}
}#二、配置方式
dubbo:
provider:
loadbalance: leastactive # 全局配置
# 方法级配置
dubbo:
references:
order-service:
methods:
- name: createOrder
loadbalance: leastactive#三、落地 Checklist
- 性能评估:评估各实例性能差异
- 策略选择:根据业务选择合适的策略
- 监控部署:监控各实例的调用量和响应时间
- 动态调整:根据监控数据动态调整权重