nginx+keepalive实现高可用热备负载均衡

2016-03-23 18:22

一、负载均衡是什么(摘自百度百科)

        负载均衡 建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。

        负载均衡,英文名称为Load Balance,其意思就是分摊到多个操作单元上进行执行,例如Web服务器、FTP服务器、企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务。

二、常用的负载均衡

    1、HTTP重定向

        HTTP 重定向可以将 HTTP 请求进行转移,在 Web 开发中我们经常会用它来完成自动跳转,比如用户登录成功后跳转到相应的管理页面。 这种重定向完全由HTTP 定义,并且由HTTP 代理和Web 服务器共同实现。很简单,当HTTP 代理(比如浏览器)向Web服务器请求某个URL后,Web 服务器可以通过HTTP 响应头信息中的Location 标记来返回一个新的URL,这意味着HTTP代理需要继续请求这个新的URL ,这便完成了自动跳转。当然,如果你自己写了一个 HTTP 代理,也可以不支持重定向,也就是对于Web 服务器返回的Location 标记视而不见,虽然这可能不符合HTTP 标准,但这完全取决于你的应用需要。 也正是因为HTTP 重定向具备了请求转移和自动跳转的本领,所以除了满足应用程序需要的各种自动跳转之外,它还可以用于实现负载均衡,以达到Web 扩展的目的。

    2、DNS负载均衡

        DNS负责提供域名解析服务,当我们访问某个站点时,实际上首先需要通过该站点域名的DNS服务器来获取域名指向的IP 地址,在这一过程中,DNS服务器完成了域名到IP 地址的映射,同样,这种映射也可以是一对多的,这时候,DNS 服务器便充当了负载均衡调度器(也称均衡器),它就像前面提到的重定向转移策略一样,将用户的请求分散到多台服务器上,但是它的实现机制完全不同。

    3、反向代理负载均衡 

        反向代理服务器的核心工作便是转发 HTTP 请求,因此它工作在 HTTP 层面,也就是 TCP 七层结构中的应用层(第七层),所以基于反向代理的负载均衡也称为七层负载均衡,实现它并不困难,目前几乎所有主流的 Web 服务器都热衷于支持基于反向代理的负载均衡。

    4、IP负载均衡 

        事实上,在数据链路层(第二层)、网络层(第三层)以及传输层(四层)都可以实现不同机制的负载均衡,但有所不同的是,这些负载均衡调度器的工作必须由Linux 内核来完成,因为我们希望网络数据包在从内核缓冲区进入进程用户地址空间之前,尽早地被转发到其他实际服务器上,没错,Linux 内核当然可以办得到,位于内核的Netfilter和IPVS可以解决问题,而用户空间的应用程序对此却束手无策。 另一方面,也正是因为可以将调度器工作在应用层以下,这些负载均衡系统可以支持更多的网络服务协议,比如FTP 、SMTP 、DNS ,以及流媒体和VoIP 等应用。

三、规划和准备

        两台相同配置的web

用途 IP
MASTER 192.168.1.100
BACKUP 192.168.1.101

四、安装

        两台接入服务器分别安装nginX和keepalived

        准备依赖包

        yum -y install gcc pcre-devel zlib-devel openssl-devel popt-devel

        下载

        wget http://nginx.org/download/nginx-1.8.1.tar.gz

        wget http://www.keepalived.org/software/keepalived-1.2.19.tar.gz

        安装nginx

        安装keepalived

        tar zxvf keepalived-1.2.19.tar.gz

        cd keepalived-1.2.19

        ./configure

        make && make install

        cp /usr/local/etc/rc.d/init.d/keepalived /etc/rc.d/init.d/

        cp /usr/local/etc/sysconfig/keepalived /etc/sysconfig/

        mkdir /etc/keepalived

        cp /usr/local/etc/keepalived/keepalived.conf /etc/keepalived/

        cp /usr/local/sbin/keepalived /usr/sbin/

        加入启动服务

        echo "/usr/local/nginx/sbin/nginx" >> /etc/rc.local

        echo "/etc/init.d/keepalived start" >> /etc/rc.local

五、配置

    1、配置nginx

        两台接入服务器的nginx的配置完全一样,主要是配置/usr/local/nginx/conf/nginx.conf的http。其中多域名指向是通过虚拟主机(配置http下面的server)实现;同一域名的不同虚拟目录通过每个server下面的不同location实现;到后端的服务器在http下面配置upstream,然后在server或location中通过proxypass引用。要实现前面规划的接入方式,http的配置如下:

    ......

    upstream opslinux.com {

            #ip_hash;                                    # ip_hash只取ip地址的前三段进行hash,不方便测试,故关掉

          server 192.168.1.102:80;

          server 192.168.1.103:80;

          server 192.168.1.104:80;

    }

    server {

            listen       80;

            server_name  opslinux.com;

            location / {

                proxy_pass http://opslinux.com;

            }

    }

    ......

    验证方法:

    首先用IP访问前表中各个应用服务器的url

    再用域名和路径访问前表中各个应用系统的域名/虚拟路径

    2、配置keepalived

        按照上面的安装方法,keepalived的配置文件在/etc/keepalived/keepalived.conf。主、从服务器的配置相关联但有所不同。如下:

    Master:

        ! Configuration File for keepalived

         global_defs {

            router_id NGINX_DEVEL

         }

        vrrp_instance VI_1 {

           state MASTER

            interface eth0

            virtual_router_id 51

            priority 100

            advert_int 1

            authentication {

                auth_type PASS

                auth_pass 1111

           }

           virtual_ipaddress {

                192.168.1.100

           }

        }

    Backup:

        ! Configuration File for keepalived

        global_defs {

          router_id NGINX_DEVEL

        } 

        vrrp_instance VI_1 {

            state BACKUP

            interface eth0

            virtual_router_id 61

            priority 99

            advert_int 1

            authentication {

                auth_type PASS

                auth_pass 1111

            }

            virtual_ipaddress {

               192.168.1.100

            }

        }

    验证方法:

        先后在主、从服务器上启动 keepalived: service keepalived start

        在主服务器上查看是否已经绑定了虚拟IP: ip addr

        停止主服务器上的keepalived: service keepalived stop 然后在从服务器上查看是否已经绑定了虚拟IP;

        启动主服务器上的keepalived,看看主服务器能否重新接管虚拟IP

    3、keepalived 监控 nginx 的状态(MASTER)

        经过前面的配置,如果主服务器的keepalived停止服务,从服务器会自动接管VIP对外服务;一旦主服务器的keepalived恢复,会重新接管VIP。 但这并不是我们需要的,我们需要的是当NginX停止服务的时候能够自动切换。

        keepalived支持配置监控脚本,我们可以通过脚本监控NginX的状态,如果状态不正常则进行一系列的操作,最终仍不能恢复NginX则杀掉keepalived,使得从服务器能够接管服务。

    如何监控NginX的状态

        最简单的做法是监控NginX进程,更靠谱的做法是检查NginX端口,最靠谱的做法是检查多个url能否获取到页面。

    如何尝试恢复服务

        如果发现NginX不正常,重启之。等待3秒再次校验,仍然失败则不再尝试。

        cd /opt

        vi chk_nginx.sh

        根据上述策略很容易写出监控脚本。这里使用nmap检查nginx端口来判断nginx的状态,记得要首先安装nmap。监控脚本如下:

        #!/bin/bash

        # check nginx server status

        NGINX=/usr/local/nginx/sbin/nginx

        PORT=80

         

        nmap localhost -p $PORT | grep "$PORT/tcp open"

        #echo $?

        if [ $? -ne 0 ];then

            $NGINX -s stop

            $NGINX

            sleep 3

            nmap localhost -p $PORT | grep "$PORT/tcp open"

            [ $? -ne 0 ] && /etc/init.d/keepalived stop

        fi

        chmod a+x /opt/chk_nginx.sh                #设置脚本的执行权限

        则 keepalived.conf中增加如下配置:

    主 keepalived

        vrrp_script chk_http_port {

            script "/opt/chk_nginx.sh"

            interval 1

            weight -2

        }

        track_script {

            chk_http_port

        }

        例子:

        ! Configuration File for keepalived

        global_defs {

           router_id NGINX_UPSTEAM

        }

        vrrp_script chk_http_port {

            script "/opt/chk_nginx.sh"

            interval 1

            weight -2

        }

        vrrp_instance VI_1 {

            state MASTER

            interface eth0

            virtual_router_id 51

            priority 100

            advert_int 1

            authentication {

                auth_type PASS

                auth_pass 1111

            }

            virtual_ipaddress {

                192.168.1.100

            }

            track_script {

                chk_http_port

            }

        }

    更进一步,为了避免启动keepalived之前没有启动nginx , 可以在/etc/init.d/keepalived的start中首先启动nginx(红色为新增部分):

        start() {

            /usr/local/nginx/sbin/nginx

            sleep 3

            echo -n $"Starting $prog: "

            daemon keepalived ${KEEPALIVED_OPTIONS}

            RETVAL=$?

            echo

            [ $RETVAL -eq 0 ] && touch /var/lock/subsys/$prog

        }