2.1.3 负载均衡架构设计
负载均衡架构是一种应用较为广泛的高可用手段,可以快速地为其他服务提供水平扩展能力。
1.什么是负载均衡架构?
如图2-4所示,无冗余结构服务端发生故障时,会直接导致系统无法访问;而使用负载均衡冗余结构,一个服务端发生故障后,依然有一个节点可以对外提供服务。如果服务端的压力过大,则可以通过增加多个服务节点来分担系统压力,这也是提高系统并发能力的直接手段。
图2-4 无冗余结构与负载均衡冗余结构的对比
负载设备可以使用硬件或软件实现,因此负载均衡可以分为硬负载(硬件设备)和软负载(软件)两种。硬负载主要使用F5、Radware等硬件设备,软负载主要使用Nginx、LVS、HAProxy等软件。
硬负载具有性能高、稳定性强的特点,但是价格昂贵,而且不利于开发人员维护。软负载具有灵活性强,易于配置的特点,但是由于软负载工具运行在操作系统之上,所以性能和稳定性受操作系统限制,相较于硬负载要略差一些。
2.负载均衡高可用方案
这种架构方式虽然解决了服务端的单节点风险,但是负载设备本身又变为了单节点。下面介绍几种常用的负载均衡高可用方案。
(1)Nginx+Keepalive双机主备方案。
如图2-5所示,部署主备两台Nginx服务器,它们各自都有自己的IP地址(10.1.8.3和10.1.8.4),在两台服务器上分别安装Keepalive服务,并绑定同一个虚拟IP(Virtual IP,VIP)地址(10.1.8.8),此IP地址要求没有被占用,客户端访问时通过VIP进行访问。
图2-5 Nginx+Keepalive双机主备架构
当主节点存活时,请求将发送至主节点处理。当主节点宕机后,VIP会自动漂移到备份节点,由备机接管负载服务,成为新的主机,从而达到主备自动切换,具备自动故障转移的能力。当故障节点恢复后,这个新的主机自动变为备机使用。
双机主备需要注意时刻保持主备Nginx的配置完全相同,避免发生系统切换后,服务无法正常使用的情况。
(2)F5+LVS/HAProxy+Nginx多级负载方案。
Nginx+Keepalive的方案虽然可以保证Nginx的高可用,但缺点是只能由一个节点对外服务,单个节点的Nginx连接数和服务能力有限,如果想对Nginx进行水平扩展就无法满足。
可以使用开源免费的LVS或HAProxy+Nginx形成二级负载结构,从而让Nginx支持水平扩展,支持超高并发请求。LVS和HAProxy都可以使用Keepalive搭建双机主备高可用模式,如图2-6所示。
图2-6 LVS/HAProxy+Nginx二级负载架构
也可以使用硬负载+LVS/HAProxy+Nginx形成三级负载结构,从而让LVS/HAProxy也支持水平扩展,并发能力将再上升一个数量级。F5和Radware可以搭建双机主备模式,保证高可用,如图2-7所示。
图2-7 硬负载+LVS/HAProxy+Nginx三级负载架构
3.四层与七层负载
LVS和HAProxy的性能比Nginx强很多,因为LVS和HAProxy专门用于四层负载,而Nginx多用于七层负载(新版本Nginx可以通过添加Stream模块,支持四层负载)。
LVS和HAProxy工作在第4层,而Nginx可以工作在第4层和第7层,如图2-8所示。
图2-8 OSI七层网络模型
LVS和HAProxy更接近于操作系统底层,使用IP加端口的方式进行路由负载,让客户端和上游服务器直接建立通信,通过TCP、UDP的请求报文头中的IP地址或MAC地址,来达到转发的目的,对网络性能几乎无损耗。
使用Nginx的七层负载时,当客户端要与服务器建立连接时,必须先和Nginx建立连接,然后Nginx再和上游服务器建立连接,所有的请求和应答都由Nginx先接收再转发出去,所以存在一定的网络和性能损耗,对CPU和内存资源损耗较大,如图2-9所示。
图2-9 七层负载请求转发
LVS和HAProxy可以工作在四层网络之上,当客户端发起请求后,LVS/HAProxy会将请求报文的IP和端口直接修改为上游服务器的IP和端口,让客户端和服务器直接建立连接,因此几乎不占用流量,对CPU和内存的消耗微乎其微,从而才具有更高的性能,如图2-10所示。
图2-10 四层负载请求转发
4.既然LVS和HAProxy这么强大,为什么还要使用Nginx呢?
由于LVS和HAProxy工作在四层网络之上,功能也比较单一,只负责请求分发,因此流量本身并不穿过它们。不支持URL路径匹配,不能做动静分离,可配置性不强。由于更接近于操作系统和网络层面,所以一般开发人员难以配置,需要专门的运维人员负责。
Nginx工作在七层网络之上,可以作为静态资源服务器、文件服务器,支持POP、SMTP协议,支持HTTP缓存、URL路径匹配,在服务器配置较好的情况下,也能够承载单机2万以上的并发,稳定性很好,配置文件简单、语法友好,开发人员可以直接配置。同时,插件众多,社区活跃度较高,通过插件可支持TCP反向代理、访问限流等功能。基于以上原因,Nginx具有极高的市场覆盖率。当然,LVS、HAProxy、Nginx都在不断地发展,未来功能差异可能会进一步缩小。
F5、Radware等硬负载设备,也是工作在四层网络之上,借助独立硬件的能力,性能最为出众,但是价格也十分高昂。
5.负载策略
客户端请求到达负载设备,需要根据一定的算法决定分发给哪一个上游服务器,这个分发算法就是负载策略,如图2-11所示。
图2-11 负载分发原理
对于不同的负载软件,支持的负载策略稍有差异,但是大体相同,有如下10种。
(1)轮询策略:请求被依次循环分发给上游服务器,一般属于默认策略,最常用。
(2)权重轮询策略:可以设置权重,权重越大,分发的请求越多,配置高的服务器权重应该大一些,配置低的服务器权重应该小一些。例如,如果设置4:1的权重,则配置高的服务器会收到4次请求,配置低的服务器会收到1次请求。
(3)动态权重策略:请求分发交由系统控制,负载均衡器会收集每个上游服务器的状态,如CPU、内存、磁盘I/O、繁忙程度等各项指标,从而计算出权重,给相对空闲的服务器分发更多请求,给繁忙的服务器分发少量请求。
(4)最小连接数策略:由于所有的连接都经过负载设备,所以它可以统计出每个上游服务器的连接数情况,每次都将请求转发给连接数最小的服务器。
(5)最短响应时长策略:将请求分发给响应时间最短的服务器。
(6)IP哈希策略:将相同来源IP的请求转发到同一个上游服务器,可用于Session保持等场景。
(7)URL哈希策略:与IP哈希策略类似,使用请求URL进行哈希计算,将相同哈希值的请求转发到相同的上游服务器。
(8)最小会话策略:根据当前的Session保持情况,将请求分发给会话最小的服务器。
(9)趋势分析策略:根据一段时间内的请求分发情况、连接数、会话、服务器状态等信息判断出每个上游服务器未来的流量上升和下降趋势,将请求转发给趋势上升的服务器。
(10)随机策略:将请求随机分发给某一个上游服务器。