常⽤负载均衡器介绍
为了保证Web应⽤程序的⾼可⽤性和性能,通常会使⽤多个应⽤服务器,然后使⽤负载均衡器接收⽤户的请求,将请求导向后端的应⽤服务器。⽬前有许多流⾏的软件可以起到负载均衡器的作⽤,它们在服务的架构有着⾮常重要的地位。
负载均衡器类型
应⽤程序通过⽹络进⾏通信,需要不同的软件和硬件合作完成。为了将复杂的问题简化,将通信过程中的相关功能各进⾏分层。开放系统互连(OSI)将⽹络通信抽象为七层模型,OSI分层模型如图1所⽰。
图1 OSI模型
按照OSI模型定义的层级,将负载均衡器分为四层负载均衡和七层负载均衡。
四层负载均衡⼯作在传输层。传输层负责处理消息的传递⽽不考虑消息的内容。HTTP协议使⽤了传输控制协议(TCP),故四层负载均衡器简单地将⽹络数据包转发到上游服务器和转发上游服务器的数据包,不检查数据包的内容。四层负载均衡器可以通过检查TCP流中的前⼏个数据包来做出有限的路由决策。
七层负载均衡器⼯作在应⽤层。HTTP就是⼯作在第七层的协议。第七层的负载均衡器的⼯作⽅式⽐第四
层的负载均衡器更复杂,它会截取流量,读取其中的信息,并根据消息的内容(如URL、cookie)作出负载均衡的决策。然后,它与选定的上游服务器建⽴新的TCP连接,并将请求写⼊服务器。
与七层负载均衡相⽐,四层负载均衡需要的计算量更⼩;在IT技术发展的早期,客户端和服务器之间的交互也不如现在复杂,所以当时四层负载均衡是⼀种更流⾏的流量处理⽅法。遵循摩尔定理,硬件在性能提⾼的同时价格也降低,现在的CPU和内存已经⾜够便宜,⼤多数的情况下,四层负载均衡的性能优势可以忽略不计。
七层负载均衡在时间和计算量⽅⾯⽐第四层更加昂贵,不过它可以提供更丰富的功能,从⽽带来更⾼的整体效率。⽐如七层负载均衡器可以确定客户端请求的数据类型,从⽽不必在所有的服务器上复制相同的数据。
Linux虚拟服务器
Linux虚拟服务器(下⾯简称LVS)是基于Linux操作系统内核的负载均衡软件。这个软件采⽤集技术,可⽤来构建⾼性能和⾼可⽤性的服务器,并提供良好的可扩展性、可靠性和可维护性。
LVS是⼯作在第四层的负载均衡软件,在各个主要⽤来构建⾼可⽤的⽹络服务,⽐如Web服务、电⼦邮件服务、媒体服务、语⾳服务等。使⽤LVS需要了解下⾯的术语:
LVS负载均衡器(LVS director)。负载均衡器⽤户接收所有传⼊的客户端请求,并将这些请求定向到特定的“真实服务器”来处理请求。
真实服务器(real server)。真实服务器是构成LVS集的节点,⽤于代表集提供服务。
虚拟IP(VIP)。LVS集对外表现的就像⼀台服务器。虚拟IP是负载均衡器为客户端提供服务的IP地址,客户端通过虚拟IP请求到集的服务。
真实IP(RIP)。真实服务器的IP地址。
控制器IP(DIP)。负载均衡器的真实IP地址。
客户端IP(CIP)。客户端的IP地址,是请求的源IP地址。
负载均衡服务器有哪些LVS有四种常见的⼯作模式。它们分别是NAT模式、直接路由模式(DR)、IP隧道模式和FULL NAT模式。
由于IPv4中定义的IP数量有限,⽣产环境中难以给所有的服务器分配公⽹IP地址。常见的做法是给机器分配⼀个内⽹IP地址,通过⽹络地址转换给客户提供服务。
当⽤户访问集提供的服务时,发往虚拟IP地址的请求数据包到达负载均衡器。负载均衡器检查⽬标地址和端⼝号。负载均衡器根据调度算法从集中选择真实服务器,然后将请求数据包中的⽬的IP地址和端⼝重写为所选服务器的IP地址和端⼝,并将数据包转发到服务器。
服务器处理完成请求后,回复数据包给负载均衡器。负载均衡器将数据包中的源IP地址和端⼝重写为虚拟服务的源IP地址和端⼝。
在这种模式下,真实服务器的必须将⽹关配置为负载均衡器的IP。不妨设⽤户请求报⽂中的源IP和端⼝分别为202.100.1.2和3456,⽬的IP 和端⼝分别为202.103.106.5和80。负载均衡器选择了服务器2,修改请求报⽂的⽬的IP和端⼝为172.16.0.3和80。
服务器2处理完成请求后,返回的报⽂中源IP和端⼝为172.16.0.3和80,⽬的IP和端⼝为202.100.1.2和3456。负载均衡器收到回复报⽂后,将回复报⽂中的源IP和端⼝修改为202.103.106.5和80。
NAT模式的⼯作过程如图2所⽰。
图2 LVS-NAT模式
NAT模式有⼀个问题:负载均衡器成为了集的瓶颈,因为所有流⼊和流出的数据包都要经过负载均衡器。直接路由(DR)解决了这个问题。
在LVS-DR模式下,真实服务器和负载均衡共享虚拟IP地址。负载均衡器的虚拟IP接⼝⽤于接收请求数据包,并将数据包路由到选定的真实服务器。真实服务器需要单独配置接⼝⽤于传输返回报⽂,并在回环接⼝配置虚拟IP地址,这是为了让真实服务器能够处理⽬标地址为虚拟IP的数据包;不能将虚拟IP设置在真实服务器的出⼝⽹卡上,否则真实服务器会响应客户端的ARP请求,从⽽造成内⽹的混乱。
负载均衡器和真实服务器必须通过集线器/交换机连接。当⽤户访问集的虚拟IP时,发送到虚拟IP地址的数据包会到达负载均衡器。负载均衡器检查数据包的⽬的IP和端⼝,选择⼀个真实服务器,然后将报⽂中⽬的MAC地址修改为选中的真实服务器的MAC地址,最后将数据包直接发送到局域⽹中。
真实服务器接收到数据包后,发现包中⽬的IP为⾃⼰配置在回环接⼝上的IP地址,因此处理这个请求,并将回复请求直接发送给客户端。DR模式的⼯作⽅式,如图3所⽰。
图3 LVS直接路由模式
采⽤DR模式的集能够处理很⼤的请求量,是⼀种应⽤⼴泛的模式。不过使⽤这种模式需要负载均衡器和真实服务器处于同⼀⼴播域中,这限制了集的可扩展性,也不利于集的异地容灾。
IP隧道模式是⽐DR模式更利于扩展的模式。IP隧道(IP封装)是⼀种将IP数据报封装在IP数据报中的技术。它允许将发往⼀个IP地址的数据报包装并重定向到另⼀个IP地址,这是⽹络中⾮常常见的技术。
在LVS的IP隧道模式中,负载均衡器收到⽤户的请求后,选择真实服务器,将数据包封装在IP数据报中,数据包中的源IP为负载均衡器的IP,⽬的IP为真实服务器的IP,最后将数据包转发到所选真实服务器。
真实服务器收到封装的数据报后,它会解封数据包冰处理请求,处理完成后将结果直接返回给请求的⽤户。
在集中,真实服务器可以拥有任意真实IP地址,也就是说真实服务器的部署可以分布不同的地理位置,只要⽀持IP隧道,让服务器能够正确解封所接收的封装数据包即可。同时要注意的是,配置虚拟IP的⽹卡不能响应ARP请求:可以在不⽀持ARP的设置上配置虚拟IP,或者将配置虚拟IP的设备发出的数据包重定向到本地套接字中。
IP隧道模式的⼯作过程,如图4所⽰。
图4 LVS隧道模式
在NAT模式下,负载均衡调度器和真实服务器必须在同⼀个VLAN下,否则负载均衡调度器⽆法作为真实服务器的⽹关。LVS的FULLNAT模式解决了这个问题。
FULLNAT模式是NAT模式的升级版。在这种模式下,负载均衡器不仅会将请求数据包中⽬的IP替换真实
服务器的IP,还会请求数据包中的源IP替换为负载均衡器的IP。在返回报⽂中,负载均衡器将报⽂⽬的IP替换为客户端的IP,并将源IP替换为虚拟IP。
FULLNAT模式不要求负载均衡器和真实服务器在同⼀个⽹段,因此可以⽀持真实服务器的跨机房部署。不过也会带来⼀定的性能损失,同时真实服务器不能直接获取到客户端的请求IP。
LVS的服务是通过名为IPVS的软件实现的,在Linux内核2.4及以上版本中,ip_vs模块已经是内核的⼀部分了。管理员通过ipvsadm程序来管理服务器集。LVS的模式在系统
下⾯演⽰如何安装和使⽤ipvsadm。在命令⾏终端中输⼊下⾯的命令:
# 安装ipvsadm
$ sudo apt-get update && sudo apt-get install ipvsadm
# 查看ipvsadm的版本
$ sudo ipvsadm -l
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
# 添加⼀台真实服务器,使⽤Round Robin调度算法
$ sudo ipvsadm -A -t 192.168.1.10:80 -s rr
# 查看真实服务器列表
$ sudo ipvsadm -l -n
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.1.10:80 rr
# 使⽤加权Round Robin算法
$ sudo ipvsadm -E -t 192.168.1.10:80 -s wrr
Nginx反向代理
Nginx既可以作为四层负载均衡器使⽤,也可以作为七层负载均衡器使⽤。这⾥将主要介绍七层负载均衡的使⽤。
Nginx我们已经很熟悉了,前⾯的章节中也演⽰了如何安装和使⽤Nginx。下⾯将重点介绍Nginx的配置。Nginx最简单的负载均衡配置如下:
# http协议块
http {
# 上游配置
upstream myapp1 {
ample;
ample;
ample;
}
# server块配置
server {
# 监听端⼝
listen 80;
# location配置
location / {
proxy_pass myapp1;
}
}
}
在上⾯的配置中,有三个实例运⾏相同的服务,这三个实例分别是srv1、srv2和srv3。默认配置下,负载均衡将使⽤循环调度算法。Nginx的代理⽀持HTTP、HTTPS、FastCGI、uwsgi、SCGI、memcached和gRPC协议。
Nginx也⽀持最少连接数算法。在某些请求需要更长时间才能完成的情况下,最少连接数算法允许更公平地控制应⽤程序实例上的负载。使⽤最少连接数算法时,Nginx将尝试优先将新请求发送给不太繁忙的服务器,⽽从避免繁忙的应⽤程序服务器过载。
在配置中使⽤least_conn指令将激活最少连接负载均衡,使⽤⽰例如下:
upstream myapp1 {
# 启⽤最⼩连接负载均衡
least_conn;
ample;
ample;
ample;
}
需要注意,使⽤循环或最少连接数算法,没有后续客户端的请求可能会发送到不同的服务器,也就是说Nginx⽆法保证同⼀客户端每次都会请求到同⼀个服务器。
如果需要将客户端绑定到特定的应⽤程序服务器,可以使⽤IP哈希负载均衡算法。使⽤这个算法,客户端的IP地址将作为哈希密钥,以确定应响应客户端请求服务器。⽤这个⽅法可以确保来⾃同⼀客户端的请求始终定向到同⼀服务器。在配置中使⽤ip_hash指令可以开启IP哈希调度,⽰例如下:
upstream myapp1 {
ip_hash;
ample;
ample;
ample;
}
可以为不同的服务器设置不同的权重,来影响负载调度的结果。上⾯的循环⽰例中没有配置服务器权重,所有的服务器都有⼀样的⼏率被负载均衡器分发请求。当为服务器指定权重参数时,调度器做负载均衡决策时,会将这个权重考虑进去,⽐如下⾯的⽰例:
upstream myapp1 {
ample weight=3;
ample;
ample;
}
采⽤了上⾯的配置后,服务器每接收5个新请求,会将3个请求定向到srv1,⼀个请求定向到srv2,⼀个请求定向到srv3。
Nginx的反向代理实现中包含了服务器运⾏状态检查。如果来⾃特定服务器的响应失败并显⽰错误,Nginx会将此服务器标记为宕机状态,在此后的⼀段时间内避免将请求定向到该服务器。
有两个指令可以⽤来设置监控检查参数:max_fails和fail_timeout。max_fails指令⽤于设置与服务器通信连续不成功的尝试次数,默认值是1,当这个值设置为0时,将不会对对应的服务器启⽤健康检查。fail_timeout参数定义Nginx将服务器标记为宕机的时间。在服务器宕机时间超过fail_timeout设置的值后,Nginx将开始使⽤正常请求探测服务器,如果探测成功,Nginx会认为服务器已经恢复正常。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论