1. nginx宕机引发的事故
通过前面学习keepalived的工作原理,我们知道keepalived实际上是通过发送VRRP广播包来检测keepalived进程是否正常,来判断nginx服务器是否挂了,从而进行nginx主备切换,因此nginx主备的说法其实不完全正确。也就是说nginx服务器高可用其实是keepalived来实现的,keepalived主机和keeaplived备机才是真正的主备关系。
因为keepalived有一个虚拟vip机制,通过vip可以绑定keepalived主机和keepalived备机的真实ip,也就是实现一个ip绑定多个机器。正是因为vip绑定了主机和备机,当主机挂了时,还有备机还可以用。
按照正常情况来说,主机挂了(nginx和keepalived都挂了),备机会立马接管主机的转发工作,肯定会发生“ip漂移”的。当主机中的keepalived挂了,nginx没挂,备机依然会接管主机的转发工作,发生“ip漂移”。
但其实这会引发一个问题,设想这么一种情况:主机中的keepalived正常运行一直在发送VRRP多播包,但主机中的nginx却挂了,而备机上运行的keepalived收到主机发来的VRRP包检测到主机中的keepalived没挂,误认为主机还在正常运行,因此就不会接管主机的转发工作,也就不会发生“ip漂移”了,从而导致用户的请求不能被正常转发。
也就是说,如果主机中的keepalived没挂,nginx却挂了,就会出现nginx和keepalived不同步的问题,跟主机断电宕机一样,虽然这种情况很少见,但一旦出现将是非常严重的宕机事故。如下图所示:
对于这种情况,应该在主机上编写nginx进程检测程序(check_nginx.sh),判断主机的nginx进程是否存在,如果主机的nginx进程挂了,那么进程检测程序应该把keepalived进程kill掉。
2. nginx进程检测脚本
在主nginx上需要编写nginx进程检测脚本(check_nginx.sh),判断nginx进程是否存在,如果nginx不存在就将keepalived进程kill掉,在主机的keepalived的配置文件下创建一个进程检测程序:check_nginx.sh,内容如下:
#!/bin/bash
# 如果进程中没有nginx则将keepalived进程kill掉
A=`ps -C nginx --no-header |wc -l` ## 查看是否有 nginx进程 把值赋给变量A
if [ $A -eq 0 ];then ## 如果没有进程值得为 零
service keepalived stop ## 则结束 keepalived 进程
fi
将主机的nginx停止,将keepalived启动
然后执行check_nginx.sh脚本
从执行可以看出check_nginx.sh脚本自动将keepalived进程kill掉了。
3. 修改keepalived配置文件
进入nginx主服务器的/etc/keepalived目录中,修改keepalived配置文件
添加下面的配置到主机nginx的keepalived.conf配置文件当中:
#全局配置
global_defs {
notification_email { #指定keepalived在发生切换时需要发送email到的对象,一行一个
XXX@XXX.com
}
notification_email_from miaoruntu@itcast.cn #指定发件人
#smtp_server XXX.smtp.com #指定smtp服务器地址
#smtp_connect_timeout 30 #指定smtp连接超时时间
router_id LVS_DEVEL #运行keepalived机器的一个标识
}
vrrp_script check_nginx {
script "/etc/keepalived/check_nginx.sh" ##监控脚本
interval 2 ##时间间隔,2秒
weight 2 ##权重
}
vrrp_instance VI_1 {
state MASTER #标示状态为MASTER 备份机为BACKUP
interface eth4 #设置实例绑定的网卡
virtual_router_id 51 #同一实例下virtual_router_id必须相同
priority 100 #MASTER权重要高于BACKUP 比如BACKUP为99
advert_int 1 #MASTER与BACKUP负载均衡器之间同步检查的时间间隔,单位是秒
authentication { #设置认证
auth_type PASS #主从服务器验证方式
auth_pass 8888
}
track_script {
check_nginx #监控脚本(可以理解为调用了check_nginx)
}
virtual_ipaddress { #设置vip
192.168.1.198 #可以多个虚拟IP,换行即可
}
}
修改后重启keepalived
注意:一定要先启动nginx,然后再启动keepalived,要不然先启动keepalived,脚本又会立马把keepalived干掉。
4. 测试
通过tail -f /var/log/messages命令查看keepalived日志,打开另一个bash终端窗口执行./nginx -s stop命令。
通过日志发现keepalived进程已经不存在,eth4已经没有绑定vip。