如何实施异构服务器的负载均衡及过载保护?

转自:2016-09-20 58沈剑 架构师之路

零、需求缘起
第一篇文章“ 一分钟了解负载均衡 ”和大家 share 了互联网架构中 反向代理层、站点层、服务层、数据层的常用负载均衡方法
第二篇文章“ lvs 为何不能完全代替 DNS 轮询 ”和大家 share 互联网接入层负载均衡需要解决的问题及架构演进
在这两篇文章中,都强调了“负载均衡是指,将请求 / 数据【均匀】分摊到多个操作单元上执行, 负载均衡的关键在于【均匀】 ”。

然而,后端的 service 有可能部署在硬件条件不同的服务器上
1)如果对标最低配的服务器“均匀”分摊负载,高配的服务器的利用率不足;
2)如果对标最高配的服务器“均匀”分摊负载,低配的服务器可能会扛不住;
能否根据异构服务器的处理能力来动态、自适应进行负载均衡及过载保护,是本文要讨论的问题
 
一、 service 层的负载均衡通常是怎么做的
一分钟了解负载均衡 ”中提到, service 层的负载均衡,一般是通过 service 连接池来实现的 ,调用方连接池会建立与下游服务多个连接,每次请求“随机”获取连接,来保证 service 访问的均衡性。
RPC-client 实现细节 ”中提到,负载均衡、故障转移、超时处理等细节也都是通过调用方连接池来实现的。
这个 调用方连接池能否实现,根据 service 的处理能力,动态 + 自适应的进行负载调度呢?
 
二、通过“静态权重”标识 service 的处理能力
调用方通过连接池组件访问下游 service ,通常采用“随机”的方式返回连接,以保证下游 service 访问的均衡性。

要打破这个随机性,最容易想到的方法,只要为每个下游 service 设置一个“权重”,代表 service 的处理能力,来调整访问到每个 service 的概率 ,例如:
假设 service-ip1 service-ip2 service-ip3 的处理能力相同,可以设置 weight1=1 weight2=1 weight3=1 ,这样三个 service 连接被获取到的概率分别就是 1/3 1/3 1/3 ,能够保证均衡访问。

假设 service-ip1 的处理能力是 service-ip2 service-ip3 的处理能力的 2 倍,可以设置 weight1=2 weight2=1 weight3=1 ,这样三个 service 连接被获取到的概率分别就是 2/4 1/4 1/4 ,能够保证处理能力强的 service 分别到等比的流量,不至于资源浪费。
 
使用 nginx 做反向代理与负载均衡,就有类似的机制。
这个方案的 优点 是: 简单 ,能够快速的实现异构服务器的负载均衡。
缺点 也很明显:这个 权重是固定的,无法自适应动态调整 ,而很多时候,服务器的处理能力是很难用一个固定的数值量化。
 
三、通过“动态权重”标识 service 的处理能力
提问:通过什么来标识一个 service 的处理能力呢?
回答: 其实一个 service 能不能处理得过来,能不能响应得过来,应该由调用方说了算。 调用服务,快速处理了,处理能力跟得上;调用服务,处理超时了,处理能力很有可能跟不上了。
 
动态权重设计
1 )用一个动态权重来标识每个 service 的处理能力,默认初始处理能力相同,即分配给每个 service 的概率相等;
2 每当 service 成功处理一个请求,认为 service 处理能力足够,权重动态 +1
3 每当 service 超时处理一个请求,认为 service 处理能力可能要跟不上了,权重动态 -10 (权重下降会更快)
4 )为了方便权重的处理,可以把权重的范围限定为 [0, 100] ,把权重的初始值设为 60

举例说明:
假设 service-ip1 service-ip2 service-ip3 的动态权重初始值 weight1=weight2=weight3=60 ,刚开始时,请求分配给这 3 service 的概率分别是 60/180 60/180 60/180 ,即负载是均衡的。

随着时间的推移,处理能力强的 service 成功处理的请求越来越多,处理能力弱的 service 偶尔有超时,随着动态权重的增减,权重可能变化成了 weight1=100 weight2=60 weight3=40 ,那么此时,请求分配给这 3 service 的概率分别是 100/200 60/200 40/200 ,即处理能力强的 service 会被分配到更多的流量。
 
四、过载保护
提问:什么是过载保护?
图示: 过载保护的负载与处理能力图(会掉底
回答 :互联网软件架构设计中所指的过载保护,是指当系统负载超过一个 service 的处理能力时, 如果 service 不进行自我保护,可能导致对外呈现处理能力为 0 ,且不能自动恢复 的现象。而 service 过载保护 ,是指即使系统负载超过一个 service 的处理能力, service 让能保证对外提供有损的稳定服务。
图示: 过载保护的负载与处理能力图 (不会掉底)
提问:如何进行过载保护?
回答 :最简易的方式, 服务端 设定一个负载阈值, 超过这个阈值的请求压过来,全部抛弃 。这个方式不是特别优雅。
 
五、如何借助“动态权重”来实施过载保护
动态权重是用来标识每个 service 的处理能力的一个值,它是 RPC-client 客户端 连接池层面的一个东东。服务端处理超时,客户端 RPC-client 连接池都能够知道,这里只要 实施一些策略,就能够对“疑似过载”的服务器进行降压 ,而不用服务器“抛弃请求”这么粗暴的实施过载保护。

应该实施一些什么样的策略呢,例如:
1 )如果某一个 service 的连接上, 连续 3 个请求都超时 ,即连续 -10 分三次,客户端就可以认为,服务器慢慢的要处理不过来了,得 service 缓一小口气 ,于是设定策略:接下来的若干时间内,例如 1 秒(或者接下来的若干个请求),请求不再分配给这个 service
2 )如果某一个 service 动态权重,降为了 0 (像连续 10 个请求超时,中间休息了 3 次还超时),客户端就可以认为,服务器完全处理不过来了,得 给这个 service 喘一大口气 ,于是设定策略:接下来的若干时间内,例如 1 分钟(为什么是 1 分钟,根据经验,此时 service 一般在发生 fullGC ,差不多 1 分钟能回过神来),请求不再分配给这个 service
3 )可以有更复杂的保护策略
 
这样的话,不但能借助“动态权重”来实施动态自适应的异构服务器负载均衡,还能在客户端层面更优雅的实施过载保护,在某个下游 service 快要响应不过来的时候,给其喘息的机会。
 
需要注意的是 :要防止客户端的过载保护引起 service 的雪崩, 如果“整体负载”已经超过了“ service 集群”的处理能力,怎么转移请求也是处理不过来的,还得通过抛弃请求来实施自我保护
 
六、总结
1 service 的负载均衡 、故障转移、超时处理 通常是 RPC-client 连接池层面来实施的
2 )异构服务器负载均衡,最简单的方式是 静态权重法 ,缺点是无法自适应动态调整
3 动态权重法 ,可以动态的根据 service 的处理能力来分配负载,需要有连接池层面的微小改动
4 过载保护 ,是在负载过高时, service 为了保护自己,保证一定处理能力的一种自救方法
5 动态权重法,还可以用做 service 的过载保护

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值