关于负载均衡算法一般是用在分布式系统中的服务协调时选择哪一台服务进行计算的算法。在dubbo,nginx,zookeeper,springcloud中的这些框架中都有用到。
下面就来总结一些常见的负载均衡算法,让大家对这些算法有一个详细的了解。最开始接触,就是nginx反向代理服务器,里面去设置负载均衡算法。如何选择哪一种负载均衡算法,这个要根据不同的应用场景去选择。没有最优的,只有最适合这种场景的。
以下总结排名不分先后:
1.轮询法
就是将请求按照顺序去重复的循环转发到对应的服务上,它均衡的对待每一台服务器,而不关心实际的连接数和当前的系统负载。
一般来说代码实现的话如下:
这里通过初始化一个serverWeightMap的Map变量来表示服务器地址和权重的映射,以此来模拟轮询算法的实现
image.png
由于serverWeightMap中的地址列表是动态的,随时可能有机器上线、下线或者宕机,因此为了避免可能出现的并发问题,如数组越界,通过新建方法内的局部变量serverMap,先将域变量复制到线程本地,以避免被多个线程修改。这样可能会引入新的问题,复制以后serverWeightMap的修改将无法反映给serverMap,也就是说,在这一轮选择服务器的过程中,新增服务器或者下线服务器,负载均衡算法中将无法获知。
新增比较好处理,而当服务器下线或者宕机时,服务消费者将有可能访问到不存在的地址。因此,在服务消费者的实现端需要考虑该问题,并且进行相应的容错处理,比如重新发起一次调用。
使用轮询的目的在于,能够均衡的把请求转移,但是付出的性能代价是非常大的。为了保证pos变量修改的互斥性,需要引入重量级悲观锁,synchronized会导致该轮询代码的并发吞吐量发生明显的下降。
2.随机法
通过系统产生的随机数,根据后端的服务器列表的大小随机选取一台。由于概率论可知,随着调用量的增大,实际效果会越来越趋于平衡。
3.源地址哈希(Hash)法
其思想就是获取客户端访问的IP地址值,通过Hash函数计算得到一个数值,用该数值对服务器列表大小进行取模运算,得到的结果就是要访问的服务器的序号。
采用Hash法进行访问,同一个IP地址的客户端,当后端服务器列表不变时,它每次都会被映射到同一台服务器上进行访问。这个特性可以在服务消费者和服务提供者之间建立有状态的session会话。
4.加权轮询法
这个算法主要是根据不同的后端服务器的配置,处理性能和当前系统的负载并不相同,抗压能力也不同。给配置高,负载低的服务器设置更高的权重,其实就是优先级只不过这里是优先级整数值越大,权重就越大。让其处理更多的请求,而低配置、高负载的话,就设置比较低的权重,降低负载(接收访问的数量,处理请求的数量)
与轮询算法类似,只是在获取服务器地址之前增加了一 段权重计算的代码,根据权重的大小,将地址重复地增加到服务器地址列表中,权重越大,该服务器每轮所获得的请求数量越多。
举例:
服务器ip 权重
127.0.0.1 3
127.0.0.2 2
127.0.0.3 1
则经过加权轮询的负载均衡算法后,访问的顺序为
127.0.0.1
127.0.0.1
127.0.0.1
127.0.0.2
127.0.0.2
127.0.0.3
。。。。(再依照以上的顺序一直循环)
- 加权随机(Weight Random)法
与加权轮询法类似,加权随机法也根据后端服务器不同的配置和负载情况,配置不同的权重。不同的是,它是按照权重来随机选取服务器的,而非顺序。
跟上一种很相似,区别就是权重越大,会被请求的概率越大。
6.最小连接数法
最小连接数算法比较灵活和智能,由于后端服务器的配置不尽相同,对于请求的处理有快有慢,它正是根据后端服务器当前的连接情况,动态地选取其中当前积压连接数最少的一 台服务器来处理当前请求,尽可能地提高后端服务器的利用效率,将负载合理地分流到每一 台机器。
感谢您阅读我的文章,整理不易,帮我点个赞,谢谢哈。
如果对文章部分还有什么见解或者疑惑,可以私信评论我,欢迎技术讨论。可以加我微信z985085305,获取我整理的一些其他的笔记。
思想的碰撞最能促进技术的进步哦
网友评论