nginx是一款非常优秀的反向代理工具,支持请求分发、负载均衡、缓存等非常实用的功能。在请求处理方面,nginx采用epoll模型,是一种基于事件监听的模型,因此具有非常高效的请求处理效率,单机并发可达百万级别。nginx收到的请求可以通过负载均衡策略分发到它的下一级应用服务器。这些服务器一般都是集群部署的。因此,在性能不足的情况下,应用服务器可以通过增加机器来扩大流量。这时候对于一些非常大的网站来说,性能瓶颈就来自于nginx,因为单机nginx的并发能力是有上限的,而且nginx本身不支持集群模式,所以此时nginx的横向扩展是只是显得特别重要。keepalived是一个用于服务器状态检测和故障转移的工具。在其配置文件中,可以配置主备服务器以及服务器的状态检测请求。也就是说,keepalived在提供服务的过程中,可以根据配置的请求不断的向指定的服务器发送请求。如果请求返回的状态码为200,表示服务器状态正常。如果不正常,那么keepalived会发送Theservergoesoffline,然后再将standbyserver设置回online。lvs是一个四层负载均衡工具。所谓四层负载均衡对应于网络的七层协议。常见的HTTP协议基于七层协议,而lvs作用于四层协议,即:传输层、网络层、数据链路层和物理层。这里传输层的主要协议是TCP和UDP协议,也就是说lvs支持的主要方式是TCP和UDP。正是因为lvs在四层负载均衡上,所以它处理请求的能力比普通服务器高很多。比如nginx的请求处理是建立在第七层网络上的,lvs的负载均衡能力是nginx的十倍以上。通过上面的介绍,我们可以发现,在一个非常大的网站中,应用服务器是可以水平扩展的,但是nginx是不支持水平扩展的,这时候nginx就会成为性能瓶颈。而lvs是一个负载均衡工具,那么如果我们将lvs和nginx结合起来,那么通过部署多台nginx服务器,通过lvs的负载均衡能力,可以将请求平均分配到每台nginx服务器上,再由nginx服务器分发到每个应用服务器,这样,我们就实现了nginx的横向扩展。由于nginx本质上也是一个应用服务器,也有可能宕机,所以这里可以结合keepalived来实现nginx的故障检测和服务切换。也就是说,通过keepalived+lvs+nginx,我们实现了nginx的高可用集群模式。在上面的介绍中,我们会注意到,虽然keepalived+lvs+nginx实现了nginx的集群模式,但是当我们使用nginx时,它本身是有ip和端口的,默认的监听端口是80和443,那么lvs是如何分配的向具有不同ip和端口的nginx服务器发出请求?这是通过虚拟ip实现的。所谓虚拟ip,就是对外提供一个公共ip,所有外部客户端都请求这个ip。lvs收到虚拟ip请求后,通过配置的调度器和负载均衡策略选择一个目标nginx服务器,然后将请求转发给该服务器。这里lvs有两个概念,分别是调度器和负载均衡策略。所谓调度器就是指lvs会如何处理请求和响应数据。主要有三种调度器:VirtualServerviaNetworkAddressTranslation(VS/NAT):这种方式的主要原理是用户向虚拟ip发送请求后,lvs会根据负载均衡算法选择一个目标处理服务,然后修改请求报文中的目标ip地址给计算出的目标服务器,发送给服务器。对于响应报文,调度器会将目标服务器返回的响应数据中的源地址修改为虚拟ip地址。这样,对于客户端来说,就正式面对了一个服务器。但是这种方式的缺点是所有的响应数据都需要经过调度器。如果请求量比较大,调度器就会成为整个系统的瓶颈。VirtualServerviaIPTunneling(VS/TUN):这种方式主要解决VS/NAT中响应数据会经过调度器的问题。和VS/NAT一样,调度器仍然会收到请求的数据,将报文中的目标ip修改为目标服务的ip,但是目标服务处理完数据后,会直接改变响应报文中的源ip修改为虚拟ip,然后向客户端发送请求。这样,响应数据由各个目标服务处理,而不需要通过调度器返回,这样会大大提高系统的吞吐量,而且由于一般的请求报文比响应报文小很多,调度器只需要处理请求消息,则系统的整体负载将在服务器之间分担。VirtualServerviaDirectRouting(VS/DR):与VS/TUN相比,这种方式的主要区别在于VS/NAT将请求报文中的ip地址修改为目标服务的ip地址,而VS/DR则不就是直接修改请求报文中的MAC地址为目标地址。这种方式效率会更高,因为VS/TUN中的ip地址还是需要转换成MAC地址才能发送数据。1、环境准备VMware;4台CentOs7虚拟主机:172.16.28.130、172.16.28.131、172.16.28.132、172.16.28.133系统服务:LVS、KeepalivedWeb服务器:nginx集群搭建:LVSDR模式2.软件安装在四台虚拟机上面,我们搭建集群172.16.28.130lvs+keepalived172.16.28.131lvs+keepalived172.16.28.132nginx172.16.28.133nginx这里我们使用172.16.28.130和172.16.28.131两台机器作为lvs+keepal的工作机器这两台机器的功能主要是负载均衡、故障检测和离线;我们使用172.16.28.132和172.16.28.133两台机器作为应用服务器,主要对外提供服务。这四台服务器作为整个后端集群,对外提供的虚拟ip为172.16.28.120。需要注意的是,这里keepalived检测到的服务是两个lvs服务器。这两台服务器其中一台为主服务器,另一台为备份服务器。两台服务器的负载均衡配置完全一样。一般情况下,当客户端请求虚拟IP时,lvs会将请求转发给master服务器,然后master服务器根据配置的负载均衡策略选择一个应用服务器,将请求发送给应用服务器进行处理。如果某个时刻,lvs的master服务器因为故障宕机了,keepalived会检测到故障,故障后下线,再让备机上线提供服务,从而实现failover功能。2.1lvs+keepalived安装在172.16.28.130和172.16.28.131上安装ipvs和keepalived:#安装ipvssudoyuminstallipvsadm#安装keepalivedsudoyuminstallkeepalived在172.16.28.132和172.16.28.133上安装nginx:#安装nginxsudoyuminstallnginx需要注意的是,在两台nginx服务器防火墙需要关闭,否则lvs+keepalived的两台机器无法向两台nginx服务器发送请求:#关闭防火墙systemctldisablefirewalld.service查看两台负载均衡机是否支持lvs:sudolsmod|grepip_vs#如果看到如下如果结果显示支持[zhangxufeng@localhost~]$sudolsmod|grepip_vsip_vs1454970nf_conntrack1372391ip_vslibcrc32c126443xfs,ip_vs,nf_conntrack如果上面的命令没有任何结果,执行sudoipvsadm命令启动ipvs,然后使用上面的命令查看.启动ipvs后,我们可以编辑/etc/keepalived/目录下的keepalived.conf文件。我们使用172.16.28.130机器作为master机器,master节点配置如下:#GlobalConfigurationglobal_defs{lvs_iddirector1#指定lvs的id}#VRRPConfigurationvrrp_instanceLVS{stateMAS#指定当前节点为主节点interfaceens33#Ens33这里是网卡名称,可以通过ifconfig或ipaddr查看virtual_router_id51#这里指定虚拟路由器id,主节点和备份节点需要指定相同的priority151#指定当前节点的优先级Level,越大值,优先级越高,master节点高于backup节点advert_int1#指定发送VRRP通知的时间间隔,以秒为单位#指定虚拟ip}}#VirtualServerConfiguration-forwwwserver#后台真实主机配置virtual_server172.16.28.12080{delay_loop1#健康检查间隔lb_algorr#负载均衡策略,这里是轮询lb_kindDR#Scheduler类型,这里是DRpersistence_time1#指定持续向同一个真实主机发送请求的时间长度。protocolTCP#指定后台访问真实主机的协议类型#RealServer1configuration#指定真实主机1的ip和端口real_server172.16.28.13280{weight1#指定当前主机的WeightTCP_CHECK{connection_timeout10#指定心跳检查的超时时间nb_get_retry3#指定心跳超时后的重复次数delay_before_retry3#指定延迟多长时间后再尝试}}#RealServer2Configurationreal_server172.16.28.13380{weight1#指定当前主机的权重TCP_CHECK{connection_timeout10#指定心跳检查的超时时间nb_get_retry3#指定心跳超时后的重复次数delay_before_retry3#指定延迟多长时间再尝试}}}上面是master节点上面keepalived的配置,对于backup节点,它的配置和master几乎一样,只是状态和优先级参数不同下面是备份节点的完整配置:#GlobalConfigurationglobal_defs{lvs_iddirector2#指定lvs的id}#VRRPConfigurationvrrp_instanceLVS{stateBACKUP#指定当前节点为主节点interfaceens33#Ens33这里是网卡的名字,可以查看virtual_router_id51通过ifconfig或ipaddr#这里指定是虚拟路由id,master节点和backup节点需要指定相同的priority150#指定当前节点的优先级,值越大优先级越高,masternode高于backup节点advert_int1#指定发送VRRP通知的时间间隔,单位是秒认证{auth_typePASS#Authentication,默认是通过auth_pass123456#认证访问密码}virtual_ipaddress{172.16.28.120#指定的虚拟ip}}#VirtualServerConfiguration-forwwwserver#后台真实主机配置virtual_server172.16.28.12080{delay_loop1#healthcheckTimeintervallb_algorr#负载均衡策略,这里是轮询lb_kindDR#Scheduler类型,这里是DRpersistence_time1#指定持续向同一个真实主机发送请求的时长protocolTCP#指定访问后台真实主机的协议类型#RealServer1configuration#指定真实主机1的ip和端口real_server172.16.28.13280{weight1#指定当前主机的权重TCP_CHECK{connection_timeout10#指定心跳检查的超时时间nb_get_retry3#指定心跳超时后的重复次数delay_before_retry3#指定在多长时间在尝试之前延迟}}#RealServer2Configurationreal_server172.16.28.13380{weight1#指定当前主机的权重TCP_CHECK{connection_timeout10#指定心跳检查的超时时间nb_get_retry3#指定心跳超时后的重复次数delay_before_retry3#指定延迟多长时间再尝试}}}之所以master和backup配置完全一样是因为当master宕机时,可以根据备份无缝切换的配置lvs+keepalived机器配置完成后,我们在下面配置两台应用服务器的nginx配置。这里我们使用nginx作为应用服务器,在其配置文件中配置返回状态码为200,返回当前主机的ip,如下:worker_processesauto;#pid/run/nginx.pid;events{worker_connections786;#pid/run/nginx.pid;events{worker_connections786;}http{server{listen80;#这里是直接返回200状态码和一个文本位置/{default_typetext/html;return200"Hello,Nginx!Serverzhangxufeng@172.16.28.133\n";}}}可以看出两台机器返回的文本中的hostip是不一样的。nginx配置完成后,可以通过以下命令启动:sudonginx启动nginx后,我们需要配置虚拟ip。这是因为我们使用的lvs调度器是DR模式。前面我们提到过,在这种模式下,客户对真实服务器的响应是由真实服务器直接返回给客户端的,而真实服务器需要将响应报文中的源ip改成虚拟ip。这里配置的虚拟ip起到了这个作用。我们编辑/etc/init.d/lvsrs文件,写入如下内容:#!/bin/bashifconfiglo:0172.16.28.120netmask255.255.255.255broadcast172.16.28.120uprouteadd-host172.16.28.120devlo:0echo"0">/proc/sys/net/ipv4/ip_forwardecho"1">/proc/sys/net/ipv4/conf/lo/arp_ignoreecho"2">/proc/sys/net/ipv4/conf/lo/arp_announceecho"1">/proc/sys/net/ipv4/conf/all/arp_ignoreecho"2">/proc/sys/net/ipv4/conf/all/arp_announceexit0lo:表示当前主机的真实网卡名称;172.16.28.120:表示虚拟ip;完成然后运行脚本文件。然后在两台lvs+keepalived机器上启动keepalived服务:sudoservicekeepalivedstart最后可以通过以下命令查看配置的lvs+keepalived策略:[zhangxufeng@localhostkeepalived]$sudoipvsadm-lnIPVirtualServerversion1.2.1(size=4096)ProtLocalAddress:PortSchedulerFlags->RemoteAddress:PortForwardWeightActiveConnInActConnTCP172.16.28.120:80rr->172.16.28.132:80Route1002.2集群测试按照以上步骤,我们已经配置了一个lvs+keepalived+nginx集群。在浏览器中,我们可以访问http://172.16.28.120看到如下响应:Hello,Nginx!服务器zhangxufeng@172.16.28.132刷新浏览器几次后,可以看到浏览器中显示的文字切换如下,这是因为lvs的负载均衡策略:你好,Nginx!服务器zhangxufeng@172.16.28.1333。小结本文首先讲解了lvs和keepalived的工作原理,介绍了它们工作的几种模式,然后介绍了lvs+keepalived+nginx,详细讲解了如何搭建nginx集群,并说明了需要注意的问题。
