vlambda博客
学习文章列表

架构设计笔记_10_关键模式_负载均衡

2020年10月 浙江衢州


负载均衡(load balance),是将请求或者负载进行平衡,合理分摊到多个计算单元或者组件上进行执行。是解决高性能和防止单点故障的最终解决办法。也是解决系统扩展性的一种手段。应用场景包括DNS,IP负载均衡,HTTP负载均衡,底层链路负载均衡等等。我们看一个http请求的示意图。


架构设计笔记_10_关键模式_负载均衡


这里的负载均衡节点,可以是硬件,也可以是软件,其主要功能就是根据一定的算法将请求分发的指定的计算单元上,上图中就是分发到指定的网站实例上。结合Runnf,上篇中提到过服务经过有状态到无状态的改造后,需要通过负载均衡来实现请求的平滑分流,这里主要处理的是http请求,所以我们这里重点讲解HTTP负载均衡。


算法


Nginx是我们常用的一种软件方案,用来解决负载均衡,是工作在七层Http协议的负载均衡系统,其官方给出的数据是在单个linux服务器上,并发可以达到5万/秒,Nginx是我们服务触达用户的最前端,那么如何将特定请求分发到指定应用实例上,是根据负载均衡算法来实现的,下面是几种常见的算法类型。


  • 任务平分类


其目的是将请求平均分配到每台服务器上,我们可以采取轮训方式进行,保证每台服务器是平均获得任务的,但是如果某台服务器挂了,负载均衡服务器是知道的,此时可以做相应的处理,比如可以将该服务器在可用服务列表中删除;但是,这种类型算法是不感知服务器本身负载的。

我们自己是知道某台服务器配置是高是低,所以我们可以通过静态配置的方式,告诉负载均衡服务器,配置高的服务器我们在分配任务时候多分点给他,这种就是加权分配方式。同样这种方式也不会关注服务器本身的负载情况。

这种类型简单明了,在某些场景下是适用的。比如大厂服务器都是配置一样的,无所谓高和低,而且在同一个地域,所以就直接平均分配就可以了。Nginx本身是自带这种算法的。


  • 性能最优类


根据服务器实际负载情况来决定处理的请求数,但是实际负载的标准可能不同,是看CPU的负载,还是网络连接请求数,或者请求响应时间等其他指标,这个要根据具体的业务来设计。这种算法复杂度很高,因为要关注服务器本身的负载情况,那就需要我们收集每个服务器的负载或者请求连接处理情况,这本身也增加了服务器的负载。所以通常这种算法是最复杂的,Nginx需要通过安装扩展才可以判断服务器的请求数,这样才知道服务器的负载情况。


  • Hash类


这种算法是根据业务属性来将一部分请求固定分配到特定的服务器上,保证会话不丢失,这个需要结合业务场景,比如电商购物网站,可以根据session id来进行hash后,转到固定的服务器上处理请求,或者某个区域范围内的请求ip都转到固定的最近的集群所在的机房来处理。Nginx内置这种算法。


以上是负载均衡算法的几大类型,具体业务场景有可能是结合这几种来实现负载均衡策略,比如华为云的负载均衡服务提供的策略。



策略落地


基于实际资源情况,我们选择基于Nginx扩展来获得服务器的处理请求数这个指标,来判断服务器的基本负载情况,然后来进行负载均衡策略,也就是选择性能最优类型的策略。所以前期文章中提出的通过zookeeper进行服务器负载状态获取的方案,考虑实际资源情况,无法实现,因为需要对Nginx进行定制开发,这个也是架构设计的合适原则,有多少人干多少活。


对于Runnf来说,Nginx的并发处理能力(50000/秒)已经基本可以满足QPS的估算了,同时Nginx只部署一台的话,也会有单点问题,所以我们通过keepalived搭建Nginx的主从集群,保证负载均衡的高可用,通过VIP(虚拟IP),对外提供唯一的入口,如下图。



以上就是负载均衡的一些主要算法说明,同时订正了Runnf的负载均衡策略,保证了架构的实际落地。通常在某个系统搭建时,都是会根据实际情况来决定负载均衡策略的,甚至有的策略是从DNS负载开始,一直到链路层都会综合使用不同的软硬件和不同的算法来实现负载均衡策略。