一、Dubbo负载均衡的几种方式
Dubbo支持以下几种负载均衡方式:
- Random LoadBalance
- RoundRobin LoadBalance
- LeastActive LoadBalance
- ConsistentHash LoadBalance
- Forking LoadBalance
- Failover LoadBalance
- Failfast LoadBalance
- Failsafe LoadBalance
具体说明如下:
- Random LoadBalance:随机选择一个服务提供者。
- RoundRobin LoadBalance:轮询选择服务提供者。
- LeastActive LoadBalance:选取活跃调用数最小的服务提供者。
- ConsistentHash LoadBalance:一致性哈希负载均衡算法。
- Forking LoadBalance:并行调用多个服务提供者,只要有一个成功就返回。
- Failover LoadBalance:失败自动切换到其他服务提供者,通常用于非幂等性的远程调用。
- Failfast LoadBalance:失败快速失败,通常用于幂等性的远程调用。
- Failsafe LoadBalance:失败安全,总是调用所有服务提供者,通常用于写入审计日志等操作。
二、Dubbo负载均衡策略
Dubbo负载均衡有两种策略,即随机和权重。下面给出Dubbo配置文件中的负载均衡配置示例:
这里设置负载均衡策略为随机,也可以设置为权重策略,示例如下:
三、Dubbo负载均衡源码
Dubbo负载均衡的源码在Dubbo的GitHub仓库中,查看地址为:https://github.com/apache/dubbo/tree/master/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/loadbalance
四、Ribbon负载均衡
Ribbon是Netflix开源的负载均衡组件,Dubbo可以集成Ribbon实现负载均衡。Ribbon的负载均衡算法可以自定义实现,Dubbo使用的是RoundRobin策略,示例配置如下:
五、Dubbo协议
Dubbo协议是Dubbo RPC通信协议的实现,其主要特点如下:
- Dubbo协议采用NIO异步通信、多路复用技术,可以提高吞吐量。
- Dubbo协议支持长连接,减少连接建立的开销。
- Dubbo协议支持多协议,可以在dubbo://、rest://等多种协议间切换。
六、Dubbo接口
Dubbo接口是Dubbo服务的提供方和消费方进行通信的契约。Dubbo服务提供者和消费者都必须引用相同的接口。
示例代码:
public interface DemoService {
String sayHello(String name);
}
七、Dubbo负载均衡算法
Dubbo负载均衡算法有多种实现方式,例如RandomLoadBalance、RoundRobinLoadBalance等。下面给出RoundRobinLoadBalance的算法简述:
- 将所有可用服务提供者存入一个有序列表list
- 如果服务提供者列表为空,则返回空;如果只有一个服务提供者,则返回该服务提供者
- 如果服务提供者列表不为空,则获取下一个服务提供者并返回
其Java代码实现如下:
public class RoundRobinLoadBalance extends AbstractLoadBalance {
private final AtomicPositiveInteger sequences = new AtomicPositiveInteger();
protected Invoker doSelect(List<Invoker> invokers, URL url, Invocation invocation) {
int length = invokers.size(); // 调用的服务数
int maxWeight = 0;
int minWeight = Integer.MAX_VALUE;
final LinkedHashMap<Invoker, IntegerWrapper> invokersWightMap = new LinkedHashMap<Invoker, IntegerWrapper>();
int weightSum = 0;
for (int i = 0; i < length; i++) {
Invoker invoker = invokers.get(i);
int weight = invoker.getUrl().getMethodParameter(invocation.getMethodName(), "weight", 100);
invokersWightMap.put(invoker, new IntegerWrapper(weight));
weightSum += weight;
maxWeight = Math.max(maxWeight, weight);
minWeight = Math.min(minWeight, weight);
}
// 不同的权重转换为相同的权重
if (maxWeight > 0 && minWeight 0) {
for (Map.Entry<Invoker, IntegerWrapper> entry : invokersWightMap.entrySet()) {
entry.setValue(new IntegerWrapper(entry.getValue().get() - minWeight));
}
weightSum -= minWeight * length;
}
}
// 循环列表进行轮转
int sequence = sequences.getAndIncrement();
if (weightSum > 0 && sequence < Integer.MAX_VALUE) {
int currentWeight = -1;
Invoker selectedInvoker = null;
int currentSequence = -1;
for (int i = 0; i weightSum) {
sequence = weightSum;
}
for (Map.Entry<Invoker, IntegerWrapper> entry : invokersWightMap.entrySet()) {
selectedInvoker = entry.getKey();
currentWeight = entry.getValue().get();
currentSequence += currentWeight;
if (currentSequence >= sequence) {
return selectedInvoker;
}
}
currentSequence = 0;
}
}
// 相同权重,随机选择
return invokers.get(ThreadLocalRandom.current().nextInt(length));
}
static class IntegerWrapper {
private int value;
public IntegerWrapper(int value) {
this.value = value;
}
public int get() {
return value;
}
public void set(int value) {
this.value = value;
}
}
}
八、Dubbo负载均衡原理
Dubbo负载均衡实现的原理如下:
- 获取所有可用服务提供者的列表,计算出他们的权重
- 根据负载均衡策略选择一个服务提供者
- 如果服务提供者无法响应,返回到第2步重新选择
- 返回选取的服务提供者
九、Dubbo负载均衡在哪层
Dubbo负载均衡在服务层,属于网络通信层。
十、Dubbo负载均衡策略如何配置选取
Dubbo负载均衡策略可以在Dubbo配置文件中进行配置,例如:
也可以通过代码进行动态设置,例如:
public class DemoConsumer {
public static void main(String[] args) {
ReferenceConfig reference = new ReferenceConfig();
reference.setInterface(DemoService.class);
reference.setLoadbalance("roundrobin");
DemoService demoService = reference.get();
String hello = demoService.sayHello("world");
System.out.println(hello);
}
}
原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/312777.html
微信扫一扫
支付宝扫一扫