nginx五 之高可用
友情提示: 高可用是在缓存模块的环境基础上搭建,缓存模块可以参考http://www.cnblogs.com/dahuandan/p/6765042.html
介绍
单点架构的应用在出现故障时,会导致系统崩溃,停止服务。为了提高系统的容错性,减少故障停机的几率,需要建立一套备份机制,在故障发生时,转移到能正常工作的服务器上,这种方式就是高可用;
nginx高可用一般通过keepalived实现,分为主备、主主两种方式,通常主主更能有效利用资源。
主备方式
配置主机
#安装keepalived yum install keepalived -y #编辑keepalived的配置文件 vi /etc/keepalived/keepalived.conf #内容如下: #全局配置,这里额外的静态路由并未添加因为它是非必要的,除非我们在当前或特定的主机上生成特殊的静态路由等 global_defs { #realserver故障时通知邮件的收件人地址,可以多个 notification_email { acassen@firewall.loc } #发件人信息(可以随意伪装,因为邮件系统不会验证处理发件人信息) notification_email_from Alexandre.Cassen@firewall.loc #发邮件的服务器(一定不可为外部地址) smtp_server 127.0.0.1 #连接超时时间 smtp_connect_timeout 30 #路由器的标识(可以随便改动) router_id LVS_DEVEL } # 定义服务状态跟踪脚本,脚本中可以检查高可用服务的状态 vrrp_script check_nginx { #这里chk_nginx.sh是定义脚本的名称,可随意取 script "/opt/check_nginx.sh" #每隔2秒钟执行一次 interval 2 #每检查一次,权重+2 weight 2 } #配置虚拟路由器的实例,VI_1是自定义的实例名称 vrrp_instance VI_1 { #初始状态,MASTER|BACKUP,当state指定的instance的初始化状态,在两台服务器都启动以后, #马上发生竞选,优先级高的成为MASTER,所以这里的MASTER并不是表示此台服务器一直是MASTER state MASTER #通告选举所用端口 interface eth0 #虚拟路由的ID号(一般不可大于255) virtual_router_id 51 #优先级信息,备必须更低 priority 101 #VRRP通告间隔,秒 advert_int 1 #认证机制 authentication { #认证类型 auth_type PASS #密码 auth_pass 1111 } #虚拟ip地址(VIP地址) virtual_ipaddress { 192.168.1.121 } #调用上面定义的服务状态跟踪脚本 track_script { check_nginx } }
配置备机
在另一台nginx服务器上配置好BACKUP,只需要修改keppalive中的state为BACKUP,priority为100即可,完整操作如下:

#安装keepalived
yum install keepalived -y
#编辑keepalived的配置文件
vi /etc/keepalived/keepalived.conf
#内容如下:
#全局配置,这里额外的静态路由并未添加因为它是非必要的,除非我们在当前或特定的主机上生成特殊的静态路由等
global_defs {
#realserver故障时通知邮件的收件人地址,可以多个
notification_email {
acassen@firewall.loc
}
#发件人信息(可以随意伪装,因为邮件系统不会验证处理发件人信息)
notification_email_from Alexandre.Cassen@firewall.loc
#发邮件的服务器(一定不可为外部地址)
smtp_server 127.0.0.1
#连接超时时间
smtp_connect_timeout 30
#路由器的标识(可以随便改动)
router_id LVS_DEVEL
}
# 定义服务状态跟踪脚本,脚本中可以检查高可用服务的状态
vrrp_script check_nginx {
#这里chk_nginx.sh是定义脚本的名称,可随意取
script "/opt/check_nginx.sh"
#每隔2秒钟执行一次
interval 2
#每检查一次,权重+2
weight 2
}
#配置虚拟路由器的实例,VI_1是自定义的实例名称
vrrp_instance VI_1 {
#初始状态,MASTER|BACKUP,当state指定的instance的初始化状态,在两台服务器都启动以后,
#马上发生竞选,优先级高的成为MASTER,所以这里的MASTER并不是表示此台服务器一直是MASTER
state BACKUP
#通告选举所用端口
interface eth0
#虚拟路由的ID号(一般不可大于255)
virtual_router_id 51
#优先级信息,备必须更低
priority 100
#VRRP通告间隔,秒
advert_int 1
#认证机制
authentication {
#认证类型
auth_type PASS
#密码
auth_pass 1111
}
#虚拟ip地址(VIP地址)
virtual_ipaddress {
192.168.1.121
}
#调用上面定义的服务状态跟踪脚本
track_script {
check_nginx
}
}
添加校验脚本
在定义好的opt目录下添加check_nginx.sh脚本文件,完整内容如下:

#!/bin/bash
#description: check service such as nginx
#set -x
CHECK_TIME=3
NGINX_OK=1
NOW=`date`
STATUS='OK!'
procnum=`ps -ef |grep "/usr/local/nginx/sbin/nginx"|grep -v "grep"|wc -l`
while [ "$CHECK_TIME" -ne 0 ]
do
let "CHECK_TIME-=1"
if [ "$procnum" -eq 1 -a -f /usr/local/nginx/logs/nginx.pid ]
then
NGINX_OK=1
CHECK_TIME=0
else
NGINX_OK=0
fi
done
if [ "$NGINX_OK" -eq 0 ]
then
status='fail!'
/etc/init.d/keepalived stop
fi
echo "$NOW:$STATUS" >> /usr/local/nginx/logs/keepalived.log
exit 0
测试主备方案
#分别启动keepalive service keepalived start #查看虚拟ip(VIP)情况 ip a #此时我们可以看到虚拟ip 192.168.1.121绑定在MASTER的eth0; #当停止MASTER所在服务器的nginx服务时,脚本会停调keepalived服务,从而将虚拟IP浮动到BACKUP #而我们依旧可以通过虚拟ip来访问应用
主主方式
配置双主
配置双主很简单,我们只需要在主备的基础上把主机的MASTER实例复制到备机上,备机的BACKUP实例复制到主机上,同时把复制的MASTAR、BACKUP的虚拟ip改为192.168.1.122,virtual_router_id改为 52即可。
完整的配置文件:

########################################服务器一#################################################
#全局配置,这里额外的静态路由并未添加因为它是非必要的,除非我们在当前或特定的主机上生成特殊的静态路由等
global_defs {
#realserver故障时通知邮件的收件人地址,可以多个
notification_email {
acassen@firewall.loc
}
#发件人信息(可以随意伪装,因为邮件系统不会验证处理发件人信息)
notification_email_from Alexandre.Cassen@firewall.loc
#发邮件的服务器(一定不可为外部地址)
smtp_server 127.0.0.1
#连接超时时间
smtp_connect_timeout 30
#路由器的标识(可以随便改动)
router_id LVS_DEVEL
}
# 定义服务状态跟踪脚本,脚本中可以检查高可用服务的状态
vrrp_script check_nginx {
#这里chk_nginx.sh是定义脚本的名称,可随意取
script "/opt/check_nginx.sh"
#每隔2秒钟执行一次
interval 2
#每检查一次,权重+2
weight 2
}
#MASTER实例,VI_1是自定义的实例名称
vrrp_instance VI_1 {
#初始状态,MASTER|BACKUP,当state指定的instance的初始化状态,在两台服务器都启动以后,
#马上发生竞选,优先级高的成为MASTER,所以这里的MASTER并不是表示此台服务器一直是MASTER
state MASTER
#通告选举所用端口
interface eth0
#虚拟路由的ID号(一般不可大于255)
virtual_router_id 51
#优先级信息,备必须更低
priority 100
#VRRP通告间隔,秒
advert_int 1
#认证机制
authentication {
#认证类型
auth_type PASS
#密码
auth_pass 1111
}
#虚拟ip地址(VIP地址)
virtual_ipaddress {
192.168.1.121
}
#调用上面定义的服务状态跟踪脚本
track_script {
check_nginx
}
}
#BACKUP实例,VI_2是自定义的实例名称
vrrp_instance VI_2 {
#初始状态,MASTER|BACKUP,当state指定的instance的初始化状态,在两台服务器都启动以后,
#马上发生竞选,优先级高的成为MASTER,所以这里的MASTER并不是表示此台服务器一直是MASTER
state BACKUP
#通告选举所用端口
interface eth0
#虚拟路由的ID号(一般不可大于255)
virtual_router_id 52
#优先级信息,备必须更低
priority 100
#VRRP通告间隔,秒
advert_int 1
#认证机制
authentication {
#认证类型
auth_type PASS
#密码
auth_pass 1111
}
#虚拟ip地址(VIP地址)
virtual_ipaddress {
192.168.1.122
}
#调用上面定义的服务状态跟踪脚本
track_script {
check_nginx
}
}
########################################服务器二#################################################
#全局配置,这里额外的静态路由并未添加因为它是非必要的,除非我们在当前或特定的主机上生成特殊的静态路由等
global_defs {
#realserver故障时通知邮件的收件人地址,可以多个
notification_email {
acassen@firewall.loc
}
#发件人信息(可以随意伪装,因为邮件系统不会验证处理发件人信息)
notification_email_from Alexandre.Cassen@firewall.loc
#发邮件的服务器(一定不可为外部地址)
smtp_server 127.0.0.1
#连接超时时间
smtp_connect_timeout 30
#路由器的标识(可以随便改动)
router_id LVS_DEVEL
}
# 定义服务状态跟踪脚本,脚本中可以检查高可用服务的状态
vrrp_script check_nginx {
#这里chk_nginx.sh是定义脚本的名称,可随意取
script "/opt/check_nginx.sh"
#每隔2秒钟执行一次
interval 2
#每检查一次,权重+2
weight 2
}
#BACKUP实例,VI_1是自定义的实例名称
vrrp_instance VI_1 {
#初始状态,MASTER|BACKUP,当state指定的instance的初始化状态,在两台服务器都启动以后,
#马上发生竞选,优先级高的成为MASTER,所以这里的MASTER并不是表示此台服务器一直是MASTER
state BACKUP
#通告选举所用端口
interface eth0
#虚拟路由的ID号(一般不可大于255)
virtual_router_id 51
#优先级信息,备必须更低
priority 100
#VRRP通告间隔,秒
advert_int 1
#认证机制
authentication {
#认证类型
auth_type PASS
#密码
auth_pass 1111
}
#虚拟ip地址(VIP地址)
virtual_ipaddress {
192.168.1.121
}
#调用上面定义的服务状态跟踪脚本
track_script {
check_nginx
}
}
#MASTER实例,VI_2是自定义的实例名称
vrrp_instance VI_2 {
#初始状态,MASTER|BACKUP,当state指定的instance的初始化状态,在两台服务器都启动以后,
#马上发生竞选,优先级高的成为MASTER,所以这里的MASTER并不是表示此台服务器一直是MASTER
state MASTER
#通告选举所用端口
interface eth0
#虚拟路由的ID号(一般不可大于255)
virtual_router_id 52
#优先级信息,备必须更低
priority 100
#VRRP通告间隔,秒
advert_int 1
#认证机制
authentication {
#认证类型
auth_type PASS
#密码
auth_pass 1111
}
#虚拟ip地址(VIP地址)
virtual_ipaddress {
192.168.1.121
}
#调用上面定义的服务状态跟踪脚本
track_script {
check_nginx
}
}
测试双主方案
#分别重新启动keepalive service keepalived restart #查看虚拟ip(VIP)情况 ip a #此时我们可以看到虚拟ip 192.168.1.121、122 分别绑定在两台服务器的eth0; #当停止某台服务器的nginx服务时,脚本会停调keepalived服务,浮动虚拟ip; #在另一台服务器执行ip a时,我们发现两个虚拟ip都绑定在该服务器的eth0; #而我们依旧可以通过两个虚拟ip来访问应用