一、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