一、Dubbo框架模型
说明:
- dubbo中有消费者Consumer,服务提供者Provider,注册中心Registry,以及RPC调用和监控中心。
- Consumer、Provider将URL信息以字符串的方式存储在注册中心,注册中心采用发布/订阅模式。
- Consumer、Provider与注册中心采用单一长连接,使用心跳模式,Provider的变更(宕机,变更资源信息)会及时通过发布/订阅模式通知到订阅者。
- Consumer寻找服务的过程称为服务发现,Provider注册URL到注册中心的过程为服务注册,Consumer通过RPC调用服务的过程为服务调用。
二、负载均衡定位
负载均衡功能:Consumer通过服务发现从注册中心拉取服务列表(Dubbo消费端将服务封装Invoker对象),Consumer在RPC调用服务之前,通过负载均衡从服务列表中选择一台服务器。
三、负载均衡接口
说明:dubbo提供负载均衡接口LoadBalance,开发者需要实现该接口,完成自己设计的select方法。
invokers:服务列表
invocation:Consumer调用服务器的传输的参数,方法名,封装在Invocatin对象中
在集群负载均衡时,Dubbo 提供了多种均衡策略,缺省为 random 随机调用。一般有选择算法 随机算法,哈希算法,加权算法,最小连接数算法。
各个算法流程图:
- 随机算法:如果各台服务器权重一样,使用随机算法选择一台服务器;否则,按照权重比率选择服务器。适应于服务器参数一致场景。
- 一致性哈希算法:相同参数的请求总是发到同一提供者,当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。缺省用 160 份虚拟节点。适应于服务器参数一致场景。
- 加权轮询算法:如果各台服务器权重一致,按照轮询选择服务器,否则,按照权重加权选择。适应于服务器参数不一致场景。
- 最小连接数算法:获取各台服务的活跃数(未处理的请求数),如果都不相等,选择最小活跃数对应的服务器,否则,判断各台服务器的权重是否相同,如果不同,按照权重加权随机选择,否则,随机选择。适应于服务器参数一致场景。
四、自适应负载均衡能力要求
- Gateway(Consumer) 端能够自动根据服务处理能力变化动态最优化分配请求保证较低响应时间,较高吞吐量;
- Provider 端能自动进行服务容量评估,当请求数量超过服务能力时,允许拒绝部分请求,以保证服务不过载;
- 当请求速率高于所有的 Provider 服务能力之和时,允许 Gateway( Consumer ) 拒绝服务新到请求。
五、自适应负载均衡设计目标
- 成功请求数最高
- TPS最大
六、自适应负载均衡与dubbo负载均衡区别
- dubbo随机算法、加权轮询算法、最小活跃数调用算法都使用到权重,但是这个权重是手动配置(写死的,无法被改变的),作为服务器的参数注册到注册中心,没有真正意义上实现自适应。
- 自适应负载均衡算法使用到的算法也离不开随机、加权、最小活跃数算法,但是权重的来源是随服务器当前运行状况动态平衡的,权重的计算来源可以是:服务器处理请求平均时长,任务队列阻塞任务数,活跃数等。
七、设计自适应负载均衡算法 – 动态计算权重
本次比赛小组计算权重是根据服务器的处理请求平均时长确定
7.1、自适应负载均衡流程设计
说明:服务器参数表是自己维护的ConcurrentHashMap,key为服务器IP,value为服务器的参数对象。
7.2、计算权重流程
- 开始接受请求:服务器都还没接收到请求时,按照轮询算法打流量,目的是为了获取各台服务器的参数,参数包括:平均处理请求时长,每台服务器的活跃数。
- 计算新权重:每台服务器都接收到请求后,根据返回参数计算每台服务器的权重,权重的计算依据每台服务器的平均处理请求时长。
weigth = weight + (500 / 平均处理时长)
即平均处理时长越短,新权重会越大。 - 按照新权重加权按照概率随机打流量:
//在总权重中随机获取一个偏移量
int offsetWeight = ThreadLocalRandom.current().nextInt(totalWeight);
//遍历服务器列表
for (遍历服务器列表) {
int currentWeight = 获取当前服务器权重;
offsetWeight = offsetWeight - currentWeight;
if (offsetWeight < 0) {
选择该服务器
}
}
7.3、如何获取服务器参数
- 请求链路图如下:
- Cal