负载均衡是指,将请求/数据分摊到多个操做单元上执行,关键在于均衡。程序员
然而,后端的服务器有可能硬件条件不一样:后端
可否根据异构服务器的处理能力来动态、自适应进行负载均衡,以及过载保护呢?服务器
service层的负载均衡,通常是经过service链接池来实现的,调用方链接池会创建与下游服务多个链接,每次请求“随机”获取链接,来保证访问的均衡性。架构
负载均衡、故障转移、超时处理等细节也都是经过调用方链接池来实现的。负载均衡
最容易想到的方法,能够为每一个下游service设置一个“权重”,表明service的处理能力,来调整访问到每一个service的几率,如上图所示:ide
(1) 假设ip1,ip2,ip3的处理能力相同,能够设置weight1=1,weight2=1,weight3=1,这样三个service链接被获取到的几率分别就是1/3,1/3,1/3,可以保证均衡访问;优化
(2) 假设ip1的处理能力是ip2,ip3的处理能力的2倍,能够设置weight1=2,weight2=1,weight3=1,这样三个service链接被获取到的几率分别就是2/4,1/4,1/4,可以保证处理能力强的service分到等比的流量,不至于资源浪费;设计
Nginx就具有相似的能力。blog
方案优势:简单粗暴,可以快速的实现异构服务器的负载均衡。ip
方案缺点:权重是固定的,没法自适应动态调整,而不少时候,服务器的处理能力是很难用一个固定的数值量化。
如何来标识一个service的处理能力呢?
服务能不能处理得过来,该由调用方说了算:
如何来设计动态权重?
能够这么玩:
(1) 用一个动态权重,来标识每一个service的处理能力,默认初始处理能力相同,即分配给每一个service的几率相等;
(2) 每当service成功处理一个请求,认为service处理能力足够,权重动态+1;
(3) 每当service超时处理一个请求,认为service处理能力可能要跟不上了,权重动态-10;
画外音:
权重降低,会比权重上升更快。
为了方便权重的处理,能够把权重的范围限定为[0, 100],把权重的初始值设为60分。
举例说明:
假设service-ip1,service-ip2,service-ip3的动态权重初始值:
随着时间的推移:
随着动态权重的增减,权重会发生变化:
如上图所示,若是没有过载保护:
过载保护,是指当外部负载超过系统处理能力时,系统会进行自我保护,依然能对外提供有损的稳定服务。
如上图所示,若是进行了过载保护:
这是最简易的方式,服务端设定一个负载阈值,超过这个阈值的请求压过来,所有抛弃。
画外音:这个方式不是特别优雅。
如同异构服务器负载均衡,仍然经过:
当一个服务端多次处理超时,权重不断下降时,链接池只要实施一些策略,就可以对“疑似过载”的服务器进行降压,而不用服务器“抛弃请求”这么粗暴的实施过载保护。
能够这么玩:
(1) 若是某一个服务器,连续3个请求都超时,即连续-10分三次,就能够认为,服务器处理不过来了,得给这个服务器喘一小口气,因而设定策略:接下来的若干时间内,例如1秒,负载再也不分配给这个服务器;
画外音:休息1秒后,再分给它。
(2) 若是某一个service的动态权重,降为了0(休息了3次还超时),就能够认为,服务器彻底处理不过来了,得给这个服务器喘一大口气,因而设定策略:接下来的若干时间内,例如1分钟,请求再也不分配给这个服务器;
画外音:根据经验,此时服务器通常在fullGC,差很少1分钟能回过神来。
这样的话,不但能借助“动态权重”来实施动态自适应的异构服务器负载均衡,还能在客户端层面更优雅的实施过载保护,在某个下游服务器快要响应不过来的时候,给其喘息的机会。
要防止过载保护引发服务器的雪崩,若是“总体负载”已经超过了“服务器集群”的处理能力,怎么转移请求也是处理不过来的。这时,仍是得经过抛弃请求来实施自我保护。
架构师之路-分享可落地的技术文章
相关推荐:
《GFS架构启示》
《Google MapReduce解决什么问题?》
《Google MapReduce巧妙优化思路?》
《程序员养女儿的四大要点!》
听说,配图值得转。