nginx接收到的请求可以通过负载均衡策略分发到其下一级的应用服务器,这些服务器 一般是以集群方式部署的,因而在性能不足的情况下,应用服务器可以通过加机器的方式扩 展流量。此时,对于一些特大型的网站,性能的瓶颈就来自于nginx了,因为单机的nginx的 并发能力是有上限的,而nginx本身是不支持集群模式的,因而此时对nginx的横向扩展就显 得尤为重要。
lvs是一款用于四层负载均衡的工具。所谓的四层负载均衡,对应的是网络七层协议, 常见的如HTTP协议是建立在七层协议上的,而lvs作用于四层协议上,也即:传输层,网络 层,数据链路层和物理层。这里的传输层主要协议有TCP和UDP协议,也就是说lvs主要支持 的方式是TCP和UDP。也正是因为lvs是处于四层负载均衡上的,因而其处理请求的能力比常 见的服务器要高非常多,比如nginx的请求处理就是建立在网络七层上的,lvs的负载均衡能 力是nginx的十倍以上。通过上面的介绍,我们可以发现,在特大型网站中,应用服务器是 可以横向扩容的,而nginx是不支持横向扩容的,此时nginx就会成为性能瓶颈。 而lvs是一款负载均衡工具,因而如果我们结合lvs和nginx,那么就可以通过部署多台 nginx服务器,通过lvs的负载均衡能力,将请求均衡的分发到各个nginx服务器上,再由 nginx服务器分发到各个应用服务器,这样,我们就实现了nginx的横向扩展了。由于lvs本质上也是一款应用服务器,因而其也有可能宕机,因而这里结合keepalived就可以实现 lvs的故障检测和服务切换。也就是说,通过keepalived+lvs+nginx,我们实现了nginx 的高可用集群模式。
总结:
Keepalived+LVS:保证lvs服务高可用。
LVS+nginx:实现nginx横向扩容。
1.VMware;
2.4台CentOs7虚拟主机:192.168.174.10, 192.168.174.11, 192.168.174.20, 192.168.174.21
3.系统服务:LVS, Keepalived
4.Web服务器:nginx
5.集群搭建:LVS DR模式
在四台虚拟机上,我们以如下方式搭建集群:
192.168.174.10 lvs+keepalived
192.168.174.11 lvs+keepalived
192.168.174.20 nginx
192.168.174.21 nginx
这里我们使用192.168.174.10 和192.168.174.11 两台机器作为lvs+keepalived 的工作机器,也就是说这两台机器的作用主要是进行负载均衡和故障检测和下线的;我们使用192.168.174.20和192.168.174.21 两台机器作为应用服务器,主要是对外提供服务的。这四台服务器作为整个后端集群服务,并且对外提供的虚拟ip是192.168.174.90 。需要说明的是,这里的keepalived 所检测的服务是两台lvs 服务器,这两台服务器,一台作为master服务器,一台作为backup服务器,两者在负载均衡的配置上是完全一样的。在正常情况下,客户端请求虚拟ip的时候,lvs 会将该请求转发到master服务器上,然后master服务器根据配置的负载均衡策略选择一台应用服务器,并且将请求发送给该应用服务器进行处理。如果在某个时刻,lvs的master服务器由于故障宕机了,keepalived就会检测到该故障,并且进行故障下线,然后将backup机器上线用于提供服务,从而实现故障转移的功能。
在192.168.174.10 和192.168.174.11 上安装ipvs和keepalived:
# 安装ipvs
sudo yum install ipvsadm
# 安装keepalived
sudo yum install keepalived
在192.168.174.20 和192.168.174.21 上安装nginx:
(可以参考另一篇博客)
https://blog.csdn.net/d234343zxdvgbh/article/details/130667386
需要注意的是,在两台nginx服务器上需要将防火墙关闭,否则lvs+keepalived的两台机器就无法将请求发送到两台nginx服务器上来:
# 关闭防火墙
systemctl disable firewalld.service
查看两台负载均衡机器是否支持lvs:
sudo lsmod |grep ip_vs
# 如果看到如下结果,则说明是支持的
[localhost ~]$ sudo lsmod|grep ip_vs
ip_vs 145497 0
nf_conntrack 137239 1 ip_vs
libcrc32c 12644 3 xfs,ip_vs,nf_conntrack
如果上述命令没有任何结果,则执行sudo ipvsadm 命令启动ipvs之后,再通过上述命令进行查看即可。
启动ipvs之后,我们就可以在/etc/keepalived/ 目录下编辑keepalived.conf 文件,我们以192.168.174.10 机器作为master机器,master节点配置如下:(用ip addr命令查看自己的网卡名称)
global_defs {
#notification_email {
# @qq.com
# }
# notification_email_from [email protected]
# smtp_server 192.168.1.14
# smtp_connection_timeout 30
router_id LVS_MASTER # 设置lvs的id,在一个网络应该是唯一的
}
vrrp_instance VI_1 {
state MASTER # 指定keepalived的角色,MASTER为主,BACKUP为备
interface eth0 # 当前进行vrrp通讯的网络接口卡(当前centos的网卡)
virtual_router_id 66 # 虚拟路由编号,主从要一直
priority 100 # 优先级,数值越大,获取处理请求的优先级越高
advert_int 1 # 检查间隔,默认为1s(vrrp组播周期秒数)
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.174.90 # 定义虚拟ip(VIP),可多设,每行一个
}
}
# 定义对外提供的LVS的VIP以及port
virtual_server 192.168.174.90 86 {
delay_loop 6 # 设置健康检查时间,单位为秒
lb_algo wrr # 设置负载调度的算法为wrr
lb_kind DR # 设置lvs实现负载的机制,有NAT、TUN、DR三个模式
nat_mask 255.255.255.0
persistence_timeout 0 # 同一IP 0秒内的请求都发到同个real server
protocol TCP
real_server 192.168.174.21 86 { # 指定real server1的ip地址
weight 3 # 配置节点权值,数值越大权重越高
TCP_CHECK {
connect_timeout 10
nb_get_retry 3
delay_before_retry 3
}
}
real_server 192.168.174.20 86 {
weight 3
TCP_CHECK {
connect_timeout 10
nb_get_retry 3
delay_before_retry 3
}
}
}
上面是master节点上keepalived的配置,对于backup节点,其配置与master几乎是一致的,只是其state和priority参数不同。如下是backup节点的完整配置:
global_defs {
#notification_email {
# @qq.com
#}
#notification_email_from [email protected]
#smtp_server 192.168.1.11
#smtp_connection_timeout 30
router_id LVS_BACKUP # 设置lvs的id,在一个网络应该是唯一的
}
vrrp_instance VI_1 {
state BACKUP # 指定keepalived的角色,MASTER为主,BACKUP为备
interface eth0 # 当前进行vrrp通讯的网络接口卡(当前进行vrrp通讯的网络接口卡)
virtual_router_id 66 # 虚拟路由编号,主从要一致
priority 99 # 优先级,数值越大,获取处理请求的优先级越高
advert_int 1 # 检查间隔,默认为1s(vrrp组播周期秒数)
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.174.90 # 定义虚拟ip(VIP),可多设,每行一个
}
}
# 定义对外提供的LVS的VIP以及port
virtual_server 192.168.174.90 86 {
delay_loop 6 # 设置健康检查时间,单位为秒
lb_algo wrr # 设置负载调度的算法为wrr
lb_kind DR # 设置lvs实现负载的机制,有NAT、TUN、DR三个模式
nat_mask 255.255.255.0
persistence_timeout 0 # 同一IP 0秒内的请求都发到同个real server
protocol TCP
real_server 192.168.174.21 86 { # 指定real server1的ip地址
weight 3 # 配置节点权值,数值越大权重越高
TCP_CHECK {
connect_timeout 10
nb_get_retry 3
delay_before_retry 3
}
}
real_server 192.168.174.20 86 {
weight 3
TCP_CHECK {
connect_timeout 10
nb_get_retry 3
delay_before_retry 3
}
}
}
启动keepalive服务,主从都要启动!
service keepalived start
在lvs+keepalived机器配置完成之后,我们下面配置两台应用服务器的nginx配置。这里我们是将nginx作为应用服务器,在其配置文件中配置返回状态码为200,并且会将当前主机的ip返回,如下是其配置: (keepalived_timeout设置为1,否则测试时会看不到效果)
server {
listen 86;
# 这里是直接返回200状态码和一段文本
location / {
default_type text/html;
return 200 "Hello, Nginx! Server [email protected]\n";
}
server {
listen 86;
# 这里是直接返回200状态码和一段文本
location / {
default_type text/html;
return 200 "Hello, Nginx! Server [email protected]\n";
}
启动nginx之后,我们需要配置虚拟ip,这是因为我们使用的lvs调度器是DR模式,前面我们讲到过,这种模式下,对客户端的响应是真实服务器直接返回给客户端的,而真实服务器需要将响应报文中的源ip修改为虚拟ip,这里配置的虚拟ip就是起这个作用的。
将这两台web服务器都配置成lvs的real server,编辑realserver脚本文件,进入指定文件夹:cd /etc/init.d/,编辑脚本文件:vim realserver,
/etc/init.d/realserver 内容如下
#!/bin/bash
# description: Config realserver lo and apply noarp
#Written by :NetSeek http://www.linuxtone.org
SNS_VIP=192.168.174.90
. /etc/rc.d/init.d/functions
case "$1" in
start)
ifconfig lo:0 $SNS_VIP netmask 255.255.255.255 broadcast $SNS_VIP
/sbin/route add -host $SNS_VIP dev lo:0
echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce
echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce
sysctl -p >/dev/null 2>&1
echo "RealServer Start OK"
;;
stop)
ifconfig lo:0 down
route del $SNS_VIP >/dev/null 2>&1
echo "0" >/proc/sys/net/ipv4/conf/lo/arp_ignore
echo "0" >/proc/sys/net/ipv4/conf/lo/arp_announce
echo "0" >/proc/sys/net/ipv4/conf/all/arp_ignore
echo "0" >/proc/sys/net/ipv4/conf/all/arp_announce
echo "RealServer Stoped"
;;
*)
echo "Usage: $0 {start|stop}"
exit 1
esac
exit 0
保存脚本文件后更改该文件权限:chmod 755 realserver,开启realserver服务:service realserver start;
根据上述步骤,我们配置完成了一个lvs+keepalived+nginx的集群。在浏览器中,我们可以访问http://192.168.174.90:86即可看到如下响应: