近期找工作,上午面试了一家公司,很久没更新博客,记录一下碰到的问题,就当查缺补漏了,哈哈
面试官:你这个使用 nginx 做负载,是使用单台 nginx 吗?如果 nginx 挂了怎么办?
我:是的,由于业务访问量不大 nginx 挂的可能性不大,考虑服务的稳定性可以使用 keepalived。
面试官:你知道实现的思路和配置吗?
我:额,没配置过。。。
传统高可用
tomcat 高可用的思路是在 tomcat 集群前面加一层负载nginx,如下图:

但是这种结构一旦 nginx 挂掉了,那么整个服务就瘫痪了
LVS思想解决高可用问题
什么是LVS
LVS是Linux Virtual Server的简写,意即Linux虚拟服务器,是一个虚拟的服务器集群系统。本项目在1998年5月由章文嵩博士成立,是中国国内最早出现的自由软件项目之一
– 摘自百度百科
LVS 个人理解就是利用多个物理机集群虚拟出一个虚拟ip(Virtual Server IP,简称VIP),虚拟ip不是实际存在的物理机,所以虚拟ip不会挂,而 LVS 的实现 Linux 内核已经帮助我们实现了,结构如下图:

nginx + keepalived
在传统高可用的基础上,利用多台服务器集群借助 keepavlied 管理 LVS 虚拟出一个虚拟ip,只要两台 nginx 服务器不宕机那么服务就不会瘫痪,如下图:

环境说明
- 演示机器ip:192.168.5.11,192.168.5.12
- Linux版本:CentOS Linux release 7.6.1810 (Core)
- keepalived版本:1.3.4
- nginx版本:1.13.1
keepalived具体配置
前提(这一步两台机器同时操作)
- 修改 selinux,关闭 SELINUX,打开
vim /etc/sysconfig/selinux
,设置SELINUX=disabled
,我 VMWare 里面安装的 Linux 和腾讯云的云服务器都默认关闭了,如下图:

- 安装需要的依赖包
1 | yum -y install libnl libnl-devel libnfnetlink-devel |
keepalived安装(这一步两台机器同时操作)
- 不要使用 yum 方式安装(有bug),keepalived 官网下载 keepalived 上传,或者使用 wget 下载,下载后解压
1
2wget https://www.keepalived.org/software/keepalived-1.3.4.tar.gz
tar -zxvf keepalived-1.3.4.tar.gz - 解压之后,指定目录注:
1
2cd keepalived-1.3.4
./configure --prefix=/usr/local/keepalived --sysconf=/etc
- –prefix:指定安装目录
- –sysconf:keepalived配置文件目录,如果指定了其他配置目录需要指定配置文件启动keepalived,如:
/usr/local/keepalived/sbin/keepalived -D -f 配置文件路径
- 编译安装
1
make && make install
keepalived配置
这一步略有不同,其中一台机器作为主机(192.168.5.11),另外一台机器作为备份机(192.168.5.12)
主机(192.168.5.11)配置
打开 keepalived 配置文件目录(我的是/etc/keepalived
)下的 keepalived.conf
文件,配置如下信息,其余多余配置删除
1 | ! Configuration File for keepalived |
备份机(192.168.5.12)配置
同样打开 keepalived 配置文件目录 ,打开 keepalived.conf 文件,配置如下信息,和主机不同的是 router_id,interface,priority,配置如下:
1 | ! Configuration File for keepalived |
校验LVS效果
- 分别启动两个机器上的 keepalived
1
/usr/local/keepalived/sbin/keepalived
- 使用
ip addr
查看效果,正常的结果是虚拟ip位于 192.168.5.11 这台机器上,因为其配置的优先级更高。可是…结果…不出意外的翻车了,哈哈哈!出现的问题是两个机器出现了双VIP,翻车截图如下:


个人猜测是防火墙的原因,于是一波 Google 大法,果不其然,找到了原因:防火墙将 vrrp 广播给拦截了,所以导致 BACKUP 接收不到 MASTER 的广播
查找问题的过程:
- 局域网内任意一台机器安装抓包工具 tcpdump,命令:
yum -y install tcpdump
- 执行
tcpdump -i ens33 vrrp -n
命令查看情况,发现两台机器都在广播,正常情况 BACKUP 不应该在广播的抓包异常情况.png - 为了验证一下,把两台机器的防火墙全部关闭,命令:
systemctl stop firewalld.service
,发现情况正常了抓包正常情况 ip addr
查看,发现配置成功了master_successbackup_success
不关闭防火墙放行 vrrp 广播
正常情况咱们肯定不裸奔需要防火墙的,那么就需要放行 vrrp 广播
1 | # 需要注意命令中的网卡名称 |
- 配置正常了,那么就需要检验一下当 MASTER 主机宕机之后虚拟ip是否会自动漂移到 BACKUP 备份机器了,当然为了模拟场景我只需要把 keepalived 服务干掉就可以了

可以看到 BACKUP 备份机已经接管了

而当 MASTER 主机重启之后,MASTER 主机又会抢回虚拟ip的控制权
nginx + keepalived配合使用
前面配置好 keepalived 之后有人会问,这和nginx貌似没啥关系,是滴,确实没啥关系,但是接下来的配置就有关系了
有时候,并非是服务器宕机了,而只是 nginx 挂掉了,而 keepalived 中并没有相关配置,这样的话如果 MASTER 主机中的 nginx 挂掉了,那么虚拟ip也不会自动飘逸到 BACKUP 备份机,接下来就是为了结合 nginx的配置,使用 keepalived 来监控 nginx
编辑心跳执行脚本
我的执行脚本位置保存在 /usr/local/keepalived/chk_nginx_pid.sh
,内容如下:
1 | #!/bin/bash |
注意:
- 保存后赋予可执行权限:
chmod +x chk_nginx_pid.sh
- 查看是否可以使用 killall 命令,如果无法使用 killall 命令则安装psmisc:
yum -y install psmisc
配置 keepalived 配置文件
增加的配置如图:

方便复制
1 | vrrp_script check_nginx { |
测试是否生效
关闭 keepalived 和 nginx的进程,重启 keepalived,看 keepalived 是否可以自动启动 nginx
1 | killall keepalived |

同理,BACKUP 备份机也同样增加相同的心跳检测脚本和配置即可
测试发现,后面无论怎么 kill 掉 nginx,nginx都会被 keepalived自动重启,变成了打不死的小强,也就实现了 nginx 的高可用