【DUBBO】dubbo的LoadBalance接口
LoadBalance负载均衡, 负责从多个 Invokers中选出具体的一个Invoker用于本次调用,调用过程中包含了负载均衡的算法,调用失败后需要重新选择
--->类注解@SPI说明可以基于Dubbo的扩展机制进行自定义的负责均衡算法实现,默认是随机算法方法注解@Adaptive说明能够生成设配方法Select方法设配类通过url的参数选择具体的算法, 在从invokers集合中根据具体的算法选择一个invoker
--->方法注解@Adaptive说明能够生成设配方法 Select方法设配类通过url的参数选择具体的算法, 在从invokers集合中根据具体的算法选择一个invoker
1. RandomLoadBalance: 随机访问策略,按权重设置随机概率,是默认策略
1)获取所有invokers的个数
2)遍历所有Invokers, 获取计算每个invokers的权重,并把权重累计加起来每相邻的两个invoker比较他们的权重是否一样,有一个不一样说明权重不均等
3)总权重大于零且权重不均等的情况下,按总权重获取随机数offset = random.netx(totalWeight);遍历invokers确定随机数offset落在哪个片段(invoker上)
4)权重相同或者总权重为0, 根据invokers个数均等选择invokers.get(random.nextInt(length))
2. RoundRobinLoadBalance:轮询,按公约后的权重设置轮询比率
1)获取轮询key 服务名+方法名
获取可供调用的invokers个数length
设置最大权重的默认值maxWeight=0
设置最小权重的默认值minWeight=Integer.MAX_VALUE
2)遍历所有Inokers,比较出得出maxWeight和minWeight
3)如果权重是不一样的
根据key获取自增序列
自增序列加一与最大权重取模默认得到currentWeigth
遍历所有invokers筛选出大于currentWeight的invokers
设置可供调用的invokers的个数length
4)自增序列加一并与length取模,从invokers获取invoker
3. LeastActiveLoadBalance: 最少活跃调用数, 相同的活跃的随机选择,
活跃数是指调用前后的计数差, 使慢的提供者收到更少的请求,因为越慢的提供者前后的计数差越大。
活跃计数的功能消费者是在ActiveLimitFilter中设置的
4. 最少活跃的选择过程如下:
1)获取可调用invoker的总个数
初始化最小活跃数,相同最小活跃的个数
相同最小活跃数的下标数组
等等
2)遍历所有invokers, 获取每个invoker的获取数active和权重
找出最小权重的invoker
如果有相同最小权重的inovkers, 将下标记录到数组leastIndexs[]数组中
累计所有的权重到totalWeight变量
3)如果invokers的权重不相等且totalWeight大于0
按总权重随机offsetWeight = random.nextInt(totalWeight)
计算随机值在哪个片段上并返回invoker
4)如果invokers的权重相等或者totalWeight等于0,均等随机
5. ConsistentHashLoadBalance:一致性hash, 相同参数的请求总是发到同一个提供者,当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。对于一致性哈希算法介绍网上很多
==============================个人学习============================
【一】Dubbo的四种负载均衡算法学习
package com.sxf.test.dubbo; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Dubbo默认实现的四种负载均衡的算法解析
* @author sxf
*
*/
public class TestDubboLoadBalance {
private static Random random = new Random(); public static void main(String[] args) {
//随机负载的策略
//testRandomLoadBalance(); //轮询的策略
testRoundRobinLoadBalance();
} /**
* Dubbo基于随机和权重算法实现的随机负载均衡的核心算法
*/
public static void testRandomLoadBalance(){
List<Invoker> invokers=new ArrayList<Invoker>();
//a机器
Invoker a=new Invoker();
a.setName("a");
a.setWeight(100); //b机器
Invoker b=new Invoker();
b.setName("b");
b.setWeight(300); //c机器
Invoker c=new Invoker();
c.setName("c");
c.setWeight(800); //添加机器列表
invokers.add(a);
invokers.add(b);
invokers.add(c);
int length=3;//三台机器 //权重不同的算法
if(false){
int totalWeight=1200;//三台机器总权重
int offset=random.nextInt(totalWeight);//随机一个小于总权重的数字
System.out.println("基于本次总权重随机出来的数字:"+offset);
for(int i=0;i<length;i++){
offset-=invokers.get(i).getWeight();
if(offset<0){
System.out.println("本次被负载到的机器为:"+invokers.get(i).getName() +" ,权重为:"+invokers.get(i).getWeight() );
return;
}
}
} //权重相同则按随机数,随机到那台机器,就是那台机器
int index=random.nextInt(length);
System.out.println("机器列表中随机一个数字为:"+index);
System.out.println("本次被负载到的机器为:"+invokers.get(index).getName());
} /**
* Dubbo的轮询调用策略算法
*
* dubbo的轮询策略,是基于【本次调用列表的list集合的下标=调用次数%服务列表个数】实现每个服务都循环调用。
* 唯独不同的是,对权重大的服务列表多轮询一次。是通过对最大权重进行取余数操作一次,刨除本轮轮询小权重的服务列表。
*
*
*/
public static void testRoundRobinLoadBalance(){
//key代表集群中的一个服务提供者的一个接口,value表示走当前消费服务器调用服务提供者的调用次数
Map<String,AtomicInteger> sequences=new ConcurrentHashMap<String,AtomicInteger>();
sequences.put("provider", new AtomicInteger()); //服务集群列表
List<Invoker> invokers=new ArrayList<Invoker>(); int length=4;
//a机器
Invoker a=new Invoker();
a.setName("a");
a.setWeight(100); //b机器
Invoker b=new Invoker();
b.setName("b");
b.setWeight(300); //c机器
Invoker c=new Invoker();
c.setName("c");
c.setWeight(800); //d机器
Invoker d=new Invoker();
d.setName("d");
d.setWeight(800); //添加机器列表
invokers.add(a);
invokers.add(b);
invokers.add(c);
invokers.add(d); //调用次数统计
Map<String,Integer> map=new HashMap<String, Integer>(); //模拟100次调用,服务提供者总共有4台机器
for(int i=0;i<100;i++){
String key="provider";//服务提供者的key
AtomicInteger integer=sequences.get(key);
int count=integer.get();
integer.compareAndSet(count,count+1);
//获取本次调用的服务
Invoker invoker=invokers.get(count%length); //统计本次调用服务的次数
Integer m=map.get(invoker.getName());
if(m==null){
map.put(invoker.getName(), new Integer(1));
}else{
int newc=m.intValue()+1;
map.put(invoker.getName(), new Integer(newc));
}
} //打印每次服务的调用次数
for(String key:map.keySet()){
System.out.println("服务【"+key+"】的调用次数"+map.get(key));
}
} /**
* 最小活跃次数,每一个服务在调用的时候,都会通过Filter
* com.alibaba.dubbo.rpc.filter.ActiveLimitFilter
* com.alibaba.dubbo.rpc.filter.ActiveLimitFilter.ExecuteLimitFilter
* 向全局的com.alibaba.dubbo.rpc.RpcStatus中统计当前调用服务提供者的活跃次数
*
* 每次在负载均衡的时候,都会通过当前服务列表去RpcStatus中拿到自己的活跃数。
* 形成一个最小活跃数的数组 int[] lestActive中记录最小活跃数或相同最小活跃数的在当前服务列表的下标。
* 如果最后最小活跃数只有一个服务提供者,则本次负载均衡就走这台服务器
* 如果最后最小活跃数相同的,就在数组中随机一个下标,从服务列表的List集合中取出一个,负载均衡到这台服务器
*
*/
public static void testLeastActiveLoadBalance(){
//下面是伪代码
List<Invoker> invokers=new ArrayList<Invoker>();
int length=invokers.size();
int[] leastIndexs = new int[length];
int lestActive=-1;//最小活跃数
int lestActiveCount=0;
for(int i=0;i<invokers.size();i++){
Invoker invoker=invokers.get(i);
Integer active=1;//从RpcStatus中拿到当前invoker的活跃次数
if(lestActive==-1||active<lestActive){
lestActive=active;
leastIndexs[0]=i;
}else if(active==lestActive){
leastIndexs[lestActiveCount++]=i;
}
}
//从相同的最小活跃数中随机选举出一个负载到这台机器上
Invoker invoker=invokers.get(leastIndexs[random.nextInt(lestActiveCount)]);
} /**
* 这个是通过你对服务提供者接口配置调用服务的参数列表,进行hash运算,然后在服务列表中基于一致性hash算法,(hash环),算出负载到那台机器节点。
* 结果,就是相同参数的调用,最终会一直被负载均衡到同一个机器节点上。前提是机器节点的个数不变。
*
* 配置如: <dubbo:service interface="..." loadbalance="consistenthash" />
或: <dubbo:reference interface="..." loadbalance="consistenthash" />
或: <dubbo:service interface="...">
<dubbo:method name="..." loadbalance="consistenthash"/>
</dubbo:service>
或: <dubbo:reference interface="...">
<dubbo:method name="..." loadbalance="consistenthash"/>
</dubbo:reference> 缺省只对第一个参数Hash,如果要修改,请配置
<dubbo:parameter key="hash.arguments" value="0,1" /> 缺省用160份虚拟节点,如果要修改,请配置
<dubbo:parameter key="hash.nodes" value="320" />
*/
public static void testConsistentHashLoadBalance(){ }
} /**
* 代表服务的机器节点
* @author sxf
*
*/
class Invoker{
//机器节点
private String name;
//权重
private int weight;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
} }
【DUBBO】dubbo的LoadBalance接口的更多相关文章
- DUBBO监控,设置接口调用数据的上报周期
目录 DUBBO监控,设置接口调用数据的上报周期 dubbo已有的监控方案 针对已有方案的改进 DUBBO监控,设置接口调用数据的上报周期 dubbo是目前比较好用的,用来实现soa架构的一个工具,d ...
- 精通Dubbo——Dubbo支持的协议的详解
转: 精通Dubbo——Dubbo支持的协议的详解 2017年06月02日 22:26:57 孙_悟_空 阅读数:44500 Dubbo支持dubbo.rmi.hessian.http.webse ...
- [dubbo] Dubbo API 笔记——配置参考
schema 配置参考 所有配置项分为三大类 服务发现:表示该配置项用于服务的注册与发现,目的是让消费方找到提供方 服务治理:表示该配置项用于治理服务间的关系,或为开发测试提供便利条件 性能调优:表示 ...
- 聊聊Dubbo - Dubbo可扩展机制实战
1. Dubbo的扩展机制 在Dubbo的官网上,Dubbo描述自己是一个高性能的RPC框架.今天我想聊聊Dubbo的另一个很棒的特性, 就是它的可扩展性. 如同罗马不是一天建成的,任何系统都一定是从 ...
- [dubbo] dubbo 基础使用
Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案.简单的说,dubbo就是个服务框架,如果没有分布式的需求,其实是不需要用的,只有在分布式的时候 ...
- Dubbo | Dubbo快速上手笔记 - 环境与配置
目录 前言 1. Dubbo相关概念 1.1 自动服务发现工作原理 2. 启动文件 2.1 zookeeper-3.4.11\bin\zkServer.cmd 2.2 zookeeper-3.4.11 ...
- 【Dubbo&&Zookeeper】3、Failed to read schema document 'http://code.alibabatech.com/schema/dubbo/dubbo.xsd'问题解决方法
转自:http://blog.csdn.net/gaoshanliushui2009/article/details/50469595 我们公司使了阿里的dubbo,但是阿里的开源网站http://c ...
- Failed to read schema document 'http://code.alibabatech.com/schema/dubbo/dubbo.xsd'问题解决方法
Failed to read schema document 'http://code.alibabatech.com/schema/dubbo/dubbo.xsd'问题解决方法 关于dubbo服务的 ...
- dubbo dubbo.xsd 报错
构建dubbo项目的时候会遇到: Multiple annotations found at this line: - cvc-complex-type.2.4.c: The matching wil ...
随机推荐
- 关于java.lang.Exception:No tests found matching的一系列解决方法
问题描述: java.lang.Exception: No tests found matching [{ExactMatcher:fDisplayName=yahaa], {ExactMatcher ...
- Android系统源代码
Android系统源代码 在线源码网站 1,http://androidxref.com 2,http://www.grepcode.com/ 3,http://www.androidos.net.c ...
- angular directive restrict 的用法
E 表示该指令是一个element; A 表示该指令是attribute; C 表示该指令是class; M 表示该指令是注视 实例如下: 原帖:www.thinkster.io/angularjs/ ...
- Linux命令详解-cal
cal命令可以用来显示公历(阳历)日历.公历是现在国际通用的历法,又称格列历,通称阳历."阳历"又名"太阳历",系以地球绕行太阳一周为一年,为西方各国所通用,故 ...
- Linux命令详解-mv
mv命令是move的缩写,可以用来移动文件或者将文件改名(move (rename) files),是Linux系统下常用的命令,经常用来备份文件或者目录. 1.命令格式: mv [选项] 源文件或目 ...
- opencv图像处理
#coding=utf-8 import cv2 import numpy as np img1 = cv2.imread("3.jpg") img2 = cv2.imread(& ...
- Python内置函数详解-总结篇
参考链接:http://www.cnblogs.com/sesshoumaru/p/6140987.html
- wordpress启动
wordpress启动 公司需要使用到wordpress 特意下载源码进行研究,才发现里面都是.php文件,需要运行php而不得不去配置运行环境 步骤如下 Wampserver32 使用的360安装的 ...
- 1.spring cloud eureka server配置
IDEA版本 2017.2.5 JDK 1.8 红色加粗内容为修改部分 1.创建一个新项目 2.选择eureka依赖 3.版本选择(重要)并且更新依赖 <?xml version="1 ...
- laravel中修改默认时区
在config文件夹下app.php中找到timezone,有RTC改成PRC