keepalived 解决入口机器(Nginx)挂掉的问题

  • 问题来源
  • DNS 轮询解决
  • LVS 解决思路
  • keepalived 配置 LVS 过程
  • 主机配置
  • 从机配置
  • 检验 keepalived 的 LVS 效果
  • keepalived 监控 Nginx
  • 主机配置
  • 从机配置
  • 双主模式 充分利用从机
  • 在 MVVM 模式中的应用


问题来源

我们有很多 Tomcat 服务器交由 Nginx 管理,可 Nginx 所在的这台机器挂了怎么办?

nginx无缘无故挂了 nginx挂掉_LVS


你可能会想到再来 2 台 Nginx 机器,一台与之前的 Nginx 并行,一台来作为最前端的网关管理这两台机器。如下图,这样中间两台机器宕机任意一个也没事。可最前端的 Nginx 也有可能挂掉,这怎么办?还是没解决问题。

nginx无缘无故挂了 nginx挂掉_DNS 轮询_02

DNS 轮询解决

有人可能会想到 DNS 轮询的方式:相同的服务,不同的机器配置同一个域名,让 DNS 轮询。这样不仅挂掉一台机器不会导致整个系统宕机,还做了一个简单的负载均衡。

nginx无缘无故挂了 nginx挂掉_高可用_03


但这样也有缺点:

1、可靠性低
如果其中的一台服务器发生故障,DNS服务器是无法知晓的,仍旧会将访问分配到此服务器。那么所有恰好访问该服务器的请求将不会有所回应。即使从 DNS 中去掉该服务器的IP,但在 Internet 上,各地区电信、网通等宽带接入商将众多的DNS存放在缓存中,以节省访问时间,DNS 更新生效需要几个小时,甚至更久。

2、负载分配不均匀
DNS负载均衡采用的是简单的轮询算法,不能区分服务器的差异,不能反映服务器的当前运行状态,不能做到为性能较好的服务器多分配请求,甚至会出现客户请求集中在某一台服务器上的情况。
用户本地计算机会缓存已解析的域名到 IP 地址的映射。当多个用户计算机都缓存了域名到某个 IP 地址的映射时,而这些用户又继续访问该域名下的网页,这时就会导致不同Web服务器间的负载分配不均匀。
负载不均匀可能导致的后果有:某几台服务器负荷很低,而另几台服务器负载很高、处理缓慢。负荷高的服务器一旦宕机,那么由于第 1 点,整个系统可能会出大量用户访问不到的情况。

LVS 解决思路

上面的问题所在的根本,其实就是最前端的机器是物理机器,物理机器是可能用着用着就挂掉的。但如果最前端的机器是一个虚拟机器呢?

nginx无缘无故挂了 nginx挂掉_DNS 轮询_04


从上图可以看到,我们用一个虚拟 IP 作为用户访问的入口,所以它自身就不存在挂掉的问题了。除非它后面的两台 Nginx 同时挂掉。这样就解决了之前的问题。这就是 LVS 的思路。

LVS 是 Linux Virtual Server 的简写,意即 Linux 虚拟服务器,是一个虚拟的服务器集群系统。
它和 Nginx 没有直接的关系,它针对的是 Linux。

keepalived 配置 LVS 过程

主机配置

  1. 关闭 SELINUX
    vim /etc/sysconfig/selinux
  2. nginx无缘无故挂了 nginx挂掉_nginx无缘无故挂了_05


  3. 安装依赖
    yum -y install libnl libnl-devel libnfnetlink-devel 你可能还需要的依赖,这些都是 Nginx 的依赖:
yum -y install autoconf automake make
yum -y install gcc gcc-c++ 
yum -y install pcre pcre-devel    
yum -y install zlib zlib-devel
yum install -y openssl openssl-devel
  1. keepalived 安装
    下载源码包:wget https://www.keepalived.org/software/keepalived-1.3.4.tar.gz 解压:tar -zxvf keepalived-1.3.4.tar.gz 进入文件夹:cd keepalived-1.3.4 配置(指定安装目录和配置目录):./configure --prefix=/usr/local/keepalived --sysconf=/etc
  2. nginx无缘无故挂了 nginx挂掉_DNS 轮询_06

  3. 编译并安装:make && make install
  4. keepalived 主机配置
    打开配置:vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived

global_defs {
   #标识当前 keepalived 机器
   router_id LVS_DEVEL
}  

vrrp_instance VI_1 {
    #状态,只能有一个是MASTER,余下的都应该为BACKUP。
    #这里只是一个标识,起不到真正的作用,主机写 BACKUP 也可以,决定主从的是下面的优先级
    state MASTER
    #网卡名字,可以用ip addr查看
    interface ens33
    #当前机器组的 id,范围是0-255
    virtual_router_id 51
    #优先级,范围1-254
    priority 100
    #心跳频率,vrrp协议通告间隔
    advert_int 1
    #授权,无需改动
    authentication {
        auth_type PASS
        auth_pass 1111
    }   
    #虚拟IP,一个就可以,要多个就换行写
    virtual_ipaddress {
        192.168.100.100
    }   
}
  1. 启动 keepalived
    /usr/local/keepalived/sbin/keepalived
  2. 检查
    ip addr
  3. nginx无缘无故挂了 nginx挂掉_DNS 轮询_07

  4. nginx

nginx无缘无故挂了 nginx挂掉_高可用_08


虚拟 IP 也可以访问

nginx无缘无故挂了 nginx挂掉_LVS_09

从机配置

相同的步骤不重复,只有第 4 步不同:

! Configuration File for keepalived

global_defs {
   #标识当前 keepalived 机器
   router_id LVS_2
}

vrrp_instance VI_1 {
    state BACKUP
    #网卡名字,可以用ip addr查看
    interface ens33
    #当前机器组的 id,和主机一样
    virtual_router_id 51
    #优先级,比主机小
    priority 80
    #心跳频率,vrrp协议通告间隔
    advert_int 1
    #授权,无需改动
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    #虚拟IP,和主机一样
    virtual_ipaddress {
        192.168.100.100
    }
}

nginx无缘无故挂了 nginx挂掉_DNS 轮询_10


从机的 ip addr 并无变化

检验 keepalived 的 LVS 效果

  1. 杀掉主机上的 keepalived,来模拟服务器宕机,观察 ip addr
    主机:
    ps -ef|grep keepalived
  2. nginx无缘无故挂了 nginx挂掉_高可用_11

  3. kill -9 40008ip addr
  4. nginx无缘无故挂了 nginx挂掉_nginx无缘无故挂了_12

  5. 发现 ip addr 里设置的 192.168.100.100 没有了
    从机:
    ip addr
  6. nginx无缘无故挂了 nginx挂掉_高可用_13

  7. 舒服了,这就证明了主机挂掉,192.168.100.100 还是可以用的。这个时候我们使用的就是从机。
  8. 再次启动主机的 keepalived:
    /usr/local/keepalived/sbin/keepalived 查看主机 ip addr
  9. nginx无缘无故挂了 nginx挂掉_DNS 轮询_14

  10. 从机 ip addr
  11. nginx无缘无故挂了 nginx挂掉_keepalived_15

  12. 可以看到,主机启动后,因为优先级高,夺走了虚拟 IP。至此,验证结束。
    如果不成功,很可能是配置里空格的问题,可以尝试重新打空格。

keepalived 监控 Nginx

不知道你有没有发现,上面的验证其实存在一个问题:假如主机没有宕机,仅仅是 Nginx 坏掉了呢?
结果是主机的 keepalived 没有结束,192.168.100.100 也访问不到了,虚拟 IP 失去了作用。这个很容易理解,不再演示。

因此,我们需要让 keepalived 监控 Nginx:

主机配置

  1. vim /etc/nginx/chk_nginx.sh
#!/bin/bash
A=`ps -C nginx --no-header |wc -l`  #统计 nginx 进程数
if [ $A -eq 0 ];then                #若为0,表明 nginx 被杀,然后
        /usr/local/openresty/nginx/sbin/nginx                #重启 nginx,我这里装的是 openresty
        if [ $A -eq 0 ];then   #如果 nginx 重启失败
              killall keepalived    #杀掉 keepalived
        fi
fi
  1. vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived

global_defs {
   router_id LVS_DEVEL
}
vrrp_script chk_http_port {
    script "/etc/nginx/chk_nginx.sh"
    interval 2
    weight 2
}

vrrp_instance VI_1 {
    state MASTER
    interface ens33
    virtual_router_id 51
    priority 200
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    track_script {
        chk_http_port
    }
    virtual_ipaddress {
       192.168.100.100
    }  
}

仔细看,增加了两处。

  1. /usr/local/keepalived/sbin/keepalived

检查

停止 Nginx:nginx -s stop 查看进程:ps -ef|grep nginx

nginx无缘无故挂了 nginx挂掉_nginx无缘无故挂了_16

从机配置

改的地方和主机一样

双主模式 充分利用从机

经过上面的所有配置之后,最前端 Nginx 挂掉的问题就已经解决了。可还有一个小问题:如果主机不宕机,从机会一直处于一个开机但无事可做的状态。我们可以充分利用从机吗?

当然可以。我们可以以从机作为主机,以从机作为主机,再配置一套 vrrp_instance。

nginx无缘无故挂了 nginx挂掉_高可用_17


当然这样就会出现新的 IP 地址,就要出现新的域名,你可以拿这台机器做其他的事。

你也可以让 DNS 轮询这两个 VIP,这样两台机器任意挂掉一台,两个 VIP 都是有效的,用户端不会因为访问挂掉的机器而获取不到资源。

在 MVVM 模式中的应用

nginx无缘无故挂了 nginx挂掉_keepalived_18