我们在使用nginx进行负载均衡时,服务器高可用了,但一旦nginx宕机,整个服务就不可用了,下面我们说下怎么将nginx也变成高可用。

1. 什么是keepalived

keepalived 是以 VRRP (Virtual Router Redundancy Protocol)协议为实现基础,VRRP是虚拟路由冗余协议,它是实现路由器高可用的协议,将多台路由器设备虚拟成一个设备,对外提供一个虚拟IP也就VIP,多台服务器里有一个master,其他都是backup, master会发组播vrrp包给backup,用于正面自己还活着,当backup收不到vrrp包时就认为master宕掉了,这时就需要根据VRRP的优先级来选举一个backup当master。

2. keepalived结合nginx

先看一眼整体架构:

nginx高可用集群部署 nginx高可用方案_nginx

3. keepalived配置

安装这里就不说了,直接看配置
(1)主节点配置

global_defs { # 全局配置
	notification_email { # 定义通知邮箱
		a@qq.com##这里写邮箱地址
   }
   notification_email_from  b@qq.com# 定义发送邮件的地址
   smtp_server 192.168.0.1 # 邮箱服务器
   smtp_connect_timeout 30   # 定义超时时间
   router_id LVS1      # 定义路由器标识信息,相同的局域网唯一,标识本节点
   vrrp_skip_check_adv_addr
   vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}
vrrp_script chk_http_port {
    script "/usr/local/src/chk_nginx_pid.sh" #心跳执行的脚本
    interval 2 #(检测脚本执行的间隔,单位是秒)
    weight 2 
# keepalived 会定时执行脚本并对脚本执行的结果进行分析,动态调整 vrrp_instance 的优先级。
# 如果脚本执行结果为 0,则优先级增加weight,否则减去weight。
}
## 定义虚拟路由, VI_1 为虚拟路由的标示符
vrrp_instance VI_1 {        # 定义实例
    state MASTER            # MASTER为主节点 MASTER,BACKUP为备份节点
    interface eth0          # 绑定虚拟 IP 的网络接口,与本机 IP 地址所在的网络接口相同
    virtual_router_id 51    # 虚拟路由的 ID 号, 两个节点设置必须一样, 可选 IP 最后一段使用     
    priority 100            # 优先级问题 
    advert_int 1            # 主备心跳通讯时间间隔
    authentication {        # 认证授权
        auth_type PASS
        auth_pass 1111
    }
	track_script {
        chk_http_port            #(调用检测脚本)
    }
    virtual_ipaddress { #虚拟ip地址,可以定义多个  
        192.168.200.16
        192.168.200.17
        192.168.200.18
    }
}

(2)备份节点
配置和主节点差不多,不同的只是自己的标识名称和状态为备用。

global_defs { # 全局配置
	notification_email { # 定义通知邮箱
		a@qq.com##这里写邮箱地址
   }
   notification_email_from  b@qq.com# 定义发送邮件的地址
   smtp_server 192.168.0.1 # 邮箱服务器
   smtp_connect_timeout 30   # 定义超时时间
   router_id LVS2      # 定义路由器标识信息,相同的局域网唯一,标识本节点
   vrrp_skip_check_adv_addr
   vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}
vrrp_script chk_http_port {
    script "/usr/local/src/chk_nginx_pid.sh" #心跳执行的脚本
    interval 2 #(检测脚本执行的间隔,单位是秒)
    weight 2 
# keepalived 会定时执行脚本并对脚本执行的结果进行分析,动态调整 vrrp_instance 的优先级。
# 如果脚本执行结果为 0,则优先级增加weight,否则减去weight。
}
## 定义虚拟路由, VI_1 为虚拟路由的标示符
vrrp_instance VI_1 {        # 定义实例
    state BACKUP            # MASTER为主节点 MASTER,BACKUP为备份节点
    interface eth0          # 绑定虚拟 IP 的网络接口,与本机 IP 地址所在的网络接口相同
    virtual_router_id 51    # 虚拟路由的 ID 号, 两个节点设置必须一样, 可选 IP 最后一段使用     
    priority 90            # 优先级问题 
    advert_int 1            # 主备心跳通讯时间间隔
    authentication {        # 认证授权
        auth_type PASS
        auth_pass 1111
    }
	track_script {
        chk_http_port            #(调用检测脚本)
    }
    virtual_ipaddress { #虚拟ip地址,可以定义多个  
        192.168.200.16
        192.168.200.17
        192.168.200.18
    }
}

(3)监控脚本

#!/bin/bash
A=`ps -C nginx --no-header |wc -l`        
if [ $A -eq 0 ];then                            
      /usr/local/nginx/sbin/nginx                #重启nginx
      if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then    #nginx重启失败,则停掉keepalived服务,进行VIP转移
              killall keepalived    #杀掉,vip就漫游到另一台机器                
      fi
fi

总结:keepalived的vip和服务器的真是ip做了映射绑定,所以当访问vip时,此时keepalived哪个节点是主节点,请求就会转发到该节点的服务器上。这点是keepalived的LVS功能,LVS有几种算法,有兴趣的可以去查下。如果主节点宕机,vip会漫游到另一个节点上。当主节点回复后,vip又会漫游回来。不过keepalived高可用比较简单,有脑裂的问题,脑裂的问题我们在后续分析zookeeper时再说明。