dubbo中的负载均衡算法:java
- RandomLoadBalance(其实是权重随机)
protected <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) { int length = invokers.size(); boolean sameWeight = true; int[] weights = new int[length]; // 获取设置的第一个节点的权重 int firstWeight = this.getWeight((Invoker)invokers.get(0), invocation); weights[0] = firstWeight; int totalWeight = firstWeight; int offset; int i; // 轮询每个节点的权重 for(offset = 1; offset < length; ++offset) { i = this.getWeight((Invoker)invokers.get(offset), invocation); // 存放全部节点的权重 weights[offset] = i; totalWeight += i; // 统计权重之和 //判断每一个节点的权重是否一致 if (sameWeight && i != firstWeight) { sameWeight = false; } } if (totalWeight > 0 && !sameWeight) { // 从总权重中返回一个随机值 offset = ThreadLocalRandom.current().nextInt(totalWeight); /** * 判断offset落在哪一个权重范围内 * 例若有三个节点 A[weight=2],B[weight=3],C[weight=5] * 假设offset = 1 * 那么: * 1 - 2 < 0 因此获得A节点 * 假设offset = 2 * 那么: * 2-2 = 0 、 0 - 3 < 0 获得B节点 * 一样假设offset = 5 * 那么: * 5 - 2 = 3 > 0 、 3 - 3 = 0 、0 - 5 < 0 获得C节点 **/ for(i = 0; i < length; ++i) { offset -= weights[i]; if (offset < 0) { return (Invoker)invokers.get(i); } } } // 若是每一个节点权重都一致的话则随机返回一个节点 return (Invoker)invokers.get(ThreadLocalRandom.current().nextInt(length)); }
- LeastActiveLoadBalance(最小活跃数)
最小活跃数负载均衡算法对应LeastActiveLoadBalance。活跃调用数越小,代表该服务提供者效率越高,单位时间内可处理更多的请求,此时应优先将请求分配给该服务提供者。
算法
- RoundRobinLoadBalance(权重轮询)
- ConsistentHashLoadBalance(一致性hash)
protected int getWeight(Invoker<?> invoker, Invocation invocation) { //获取权重值,默认为100 int weight = invoker.getUrl().getMethodParameter(invocation.getMethodName(), "weight",100); if (weight > 0) { //服务提供者启动时间戳 long timestamp = invoker.getUrl().getParameter("remote.timestamp", 0L); if (timestamp > 0L) { //当前时间-启动时间=运行时长 int uptime = (int) (System.currentTimeMillis() - timestamp); //获取服务预热时间 默认10分钟 int warmup = invoker.getUrl().getParameter("warmup", 600000 ); //若是服务运行时间小于预热时间,即服务启动未到达10分钟 if (uptime > 0 && uptime < warmup) { //从新计算服务权重 weight = calculateWarmupWeight(uptime, warmup, weight); } } } return weight; }