一次面试过程中...
一、传统高可用
tomcat 高可用的思路是在 tomcat 集群前面加一层负载nginx,如下图:
但是这种结构一旦 nginx 挂掉了,那么整个服务就瘫痪了。
二、LVS思想解决高可用问题
1. 什么是LVS
LVS 个人理解就是利用多个物理机集群虚拟出一个虚拟ip(Virtual Server IP,简称VIP),虚拟ip不是实际存在的物理机,所以虚拟ip不会挂,而 LVS 的实现 Linux 内核已经帮助我们实现了,结构如下图:
2. 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具体配置
1. 前提
注意:两台机器都需要进行此步操作
1、修改 selinux,关闭 SELINUX,打开 vim /etc/sysconfig/selinux
,设置 SELINUX=disabled
,我 VMWare 里面安装的 Linux 和腾讯云的云服务器都默认关闭了,如下图:
2、安装需要的依赖包。
yum -y install libnl libnl-devel libnfnetlink-devel
2. keepalived安装
注意:两台机器都需要进行此步操作
1、不要使用 yum 方式安装(有bug),keepalived 官网下载 keepalived 上传,或者使用 wget 下载,下载后解压。
wget https://www.keepalived.org/software/keepalived-1.3.4.tar.gz
tar -zxvf keepalived-1.3.4.tar.gz
2、解压之后,指定目录。
cd keepalived-1.3.4
./configure --prefix=/usr/local/keepalived --sysconf=/etc
注:
- --prefix:指定安装目录。
- --sysconf:keepalived配置文件目录,如果指定了其他配置目录需要指定配置文件启动keepalived,如:
/usr/local/keepalived/sbin/keepalived -D -f 配置文件路径
。
3、编译安装。
make && make install
3. keepalived配置
这一步略有不同,其中一台机器作为主机(192.168.5.11),另外一台机器作为备份机(192.168.5.12)
主机(192.168.5.11)配置
打开 keepalived 配置文件目录(我的是/etc/keepalived
)下的 keepalived.conf
文件,配置如下信息,其余多余配置删除。
! Configuration File for keepalived
global_defs {
router_id 192.168.5.11 # keepalived的唯一标识
}
vrrp_instance VI_1 {
state MASTER # 初始状态,MASTER 和 BACKUP
interface ens33 # 系统使用的网卡接口名称,可以使用ip addr查看
virtual_router_id 51 # 组名,参与此虚拟机ip的机器配置一样的值,即一个集群内的机器都使用同一个值
priority 200 # 优先级,数值大的优先级高,组内最高的胜出
advert_int 1 # 心跳检测1秒一次
authentication { # 授权,无需改动
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.5.10 # 虚拟ip
}
}
备份机(192.168.5.12)配置
同样打开 keepalived 配置文件目录 ,打开 keepalived.conf 文件,配置如下信息,和主机不同的是 router_id,interface,priority,配置如下:
! Configuration File for keepalived
global_defs {
router_id 192.168.5.12 # keepalived的唯一标识
}
vrrp_instance VI_1 {
state BACKUP # 初始状态,MASTER 和 BACKUP
interface ens33 # 系统使用的网卡接口名称,可以使用ip addr查看
virtual_router_id 51 # 组名,参与此虚拟机ip的机器配置一样的值,即一个集群内的机器都使用同一个值
priority 100 # 优先级,数值大的优先级高,组内最高的胜出
advert_int 1 # 心跳检测1秒一次
authentication { # 授权,无需改动
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.5.10 # 虚拟ip
}
}
4. 校验LVS效果
1、分别启动两个机器上的 keepalived。
/usr/local/keepalived/sbin/keepalived
2、使用 ip addr
查看效果,正常的结果是虚拟ip位于 192.168.5.11 这台机器上,因为其配置的优先级更高。可是...结果...不出意外的翻车了,哈哈哈!出现的问题是两个机器出现了双VIP,翻车截图如下:
个人猜测是防火墙的原因,于是一波 Google 大法,果不其然,找到了原因:防火墙将 vrrp 广播给拦截了,所以导致 BACKUP 接收不到 MASTER 的广播。
查找问题的过程:
局域网内任意一台机器安装抓包工具 tcpdump,命令:yum -y install tcpdump
执行 tcpdump -i ens33 vrrp -n
命令查看情况,发现两台机器都在广播,正常情况 BACKUP 不应该在广播的。
为了验证一下,把两台机器的防火墙全部关闭,命令:systemctl stop firewalld.service
,发现情况正常了。
ip addr
查看,发现配置成功了。
不关闭防火墙放行 vrrp 广播
正常情况咱们肯定不裸奔需要防火墙的,那么就需要放行 vrrp 广播。
# 需要注意命令中的网卡名称
firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 --in-interface ens33 --destination 224.0.0.18 --protocol vrrp -j ACCEPT
# 重启防火墙
firewall-cmd --reload
3、配置正常了,那么就需要检验一下当 MASTER 主机宕机之后虚拟ip是否会自动漂移到 BACKUP 备份机器了,当然为了模拟场景我只需要把 keepalived 服务干掉就可以了。
可以看到 BACKUP 备份机已经接管了。
而当 MASTER 主机重启之后,MASTER 主机又会抢回虚拟ip的控制权。
五、nginx+keepalived配合使用
前面配置好 keepalived 之后有人会问,这和nginx貌似没啥关系,是滴,确实没啥关系,但是接下来的配置就有关系了。
有时候,并非是服务器宕机了,而只是 nginx 挂掉了,而 keepalived 中并没有相关配置,这样的话如果 MASTER 主机中的 nginx 挂掉了,那么虚拟ip也不会自动飘逸到 BACKUP 备份机,接下来就是为了结合 nginx的配置,使用 keepalived 来监控 nginx 。
1. 编辑心跳执行脚本
我的执行脚本位置保存在 /usr/local/keepalived/chk_nginx_pid.sh
,内容如下:
#!/bin/bash
A=`ps -C nginx --no-header |wc -l` # 统计nginx进程数,若为0,表明nginx被杀
if [ $A -eq 0 ];then
# 重启nginx,不是默认配置路径所以需要指定路径,因人而异
/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
# nginx重启失败,则停掉keepalived服务,进行VIP转移
if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then
# 杀掉,VIP就漫游到另一台机器
killall keepalived
fi
fi
注意:
- 保存后赋予可执行权限:
chmod +x chk_nginx_pid.sh
- 查看是否可以使用 killall 命令,如果无法使用 killall 命令则安装psmisc:
yum -y install psmisc
2. 配置keepalived配置文件
增加的配置如图:
vrrp_script check_nginx {
script "/usr/local/keepalived/check_nginx.sh" # 心跳执行的脚本
interval 2 # 每2秒检测一次
weight 2 # 脚本结果导致的优先级变更:10表示优先级+10;-10则表示优先级-10
}
track_script {
check_nginx # 调用检测脚本
}
3. 测试是否生效
关闭 keepalived 和 nginx的进程,重启 keepalived,看 keepalived 是否可以自动启动 nginx 。
killall keepalived
killall nginx
/usr/local/keepalived/sbin/keepalived
同理,BACKUP 备份机也同样增加相同的心跳检测脚本和配置即可 。
测试发现,后面无论怎么 kill 掉 nginx,nginx都会被 keepalived自动重启,变成了打不死的小强,也就实现了 nginx 的高可用。