Nginx配合keepalived实现双主负载均衡

jopen 9年前

前言:由于之前一直使用的是主从高可用加后端负载,随着业务量的增大,前端一台服务在高峰时期有些吃力,所有对之前架构进行了一点改造,把主从升级 成了双主,可以更充分的利用现有服务器资源,由于实验环境有限,后端的测试仅仅使用了一个静态页面,没有搭建动态环境,也没用使用数据库,如有需要可以参 考其他文档。

一、架构规划

1、服务器IP地址规划

VIP1:192.168.1.149

VIP2:192.168.1.150

Keepalived1:192.168.1.151

Keepalived2:192.168.1.152

WebServer1:192.168.1.201

WebServer2:192.168.1.202

2、服务器操作系统

所使用的操作系统均为CentOS release 6.6 (Final) x86_64,最小化安装。

3、网络拓扑图

Nginx配合keepalived实现双主负载均衡

二、配置Nginx代理服务器

此部分Node1与Node2的配置完全相同。

1,准备编译环境

1
# yum –y install gccgcc-c++ pcre-devel openssl openssl-devel wget

2,编译安装nginx

   
  1. # ./configure \  
  2.  --prefix=/usr/local/nginx \  
  3.  --sbin-path=/usr/local/nginx/sbin/nginx \  
  4.  --conf-path=/etc/nginx/nginx.conf \  
  5.  --error-log-path=/var/log/nginx/error.log \  
  6.  --http-log-path=/var/log/nginx/access.log \  
  7.  --pid-path=/var/run/nginx/nginx.pid \  
  8.  --lock-path=/var/lock/nginx.lock \  
  9.  --user=nginx \  
  10.  --group=nginx \  
  11.  --with-http_ssl_module \  
  12.  --with-pcre  
  13. # make && make install 

3,为nginx提供SysV init脚本:

# vi /etc/rc.d/init.d/nginx

添加如下内容

   
  1. #!/bin/sh  
  2. #  
  3. # nginx - this script starts and stopsthe nginx daemon  
  4. #  
  5. # chkconfig:   - 85 15   
  6. # description:  Nginx is an HTTP(S) server, HTTP(S) reverse \  
  7. #               proxy and IMAP/POP3 proxy server  
  8. # processname: nginx  
  9. # config:      /etc/nginx/nginx.conf  
  10. # config:      /etc/sysconfig/nginx  
  11. # pidfile:     /var/run/nginx.pid  
  12. # Source function library.  
  13. . /etc/rc.d/init.d/functions  
  14. # Source networking configuration.  
  15. . /etc/sysconfig/network  
  16. # Check that networking is up.  
  17. [ "$NETWORKING" = "no"] && exit 0  
  18. nginx="/usr/local/nginx/sbin/nginx" 
  19. prog=$(basename $nginx)  
  20. NGINX_CONF_FILE="/etc/nginx/nginx.conf" 
  21. [ -f /etc/sysconfig/nginx ] && ./etc/sysconfig/nginx  
  22. lockfile=/var/lock/subsys/nginx  
  23. make_dirs() {  
  24.   # make required directories  
  25.   user=`nginx -V 2>&1 | grep "configure arguments:" | sed's/[^*]*--user=\([^ ]*\).*/\1/g' -`  
  26.   options=`$nginx -V 2>&1 | grep 'configure arguments:'`  
  27.   for opt in $options; do  
  28.       if [ `echo $opt | grep '.*-temp-path'` ]; then  
  29.            value=`echo $opt | cut -d"=" -f 2`  
  30.            if [ ! -d "$value" ]; then  
  31.                # echo "creating"$value  
  32.                mkdir -p $value && chown-R $user $value  
  33.            fi  
  34.       fi  
  35.   done  
  36. }  
  37. start() {  
  38.    [ -x $nginx ] || exit 5  
  39.    [ -f $NGINX_CONF_FILE ] || exit 6  
  40.    make_dirs  
  41.    echo -n $"Starting $prog: "  
  42.    daemon $nginx -c $NGINX_CONF_FILE  
  43.    retval=$?  
  44.    echo  
  45.    [ $retval -eq 0 ] && touch $lockfile  
  46.    return $retval  
  47. }  
  48. stop() {  
  49.    echo -n $"Stopping $prog: "  
  50.    killproc $prog -QUIT  
  51.    retval=$?  
  52.    echo  
  53.    [ $retval -eq 0 ] && rm -f $lockfile  
  54.    return $retval  
  55. }  
  56. restart() {  
  57.    configtest || return $?  
  58.    stop  
  59.    sleep 1  
  60.    start  
  61. }  
  62. reload() {  
  63.    configtest || return $?  
  64.    echo -n $"Reloading $prog: "  
  65.    killproc $nginx -HUP  
  66.    RETVAL=$?  
  67.    echo  
  68. }  
  69. force_reload() {  
  70.    restart  
  71. }  
  72. configtest() {  
  73.  $nginx -t -c $NGINX_CONF_FILE  
  74. }  
  75. rh_status() {  
  76.    status $prog  
  77. }  
  78. rh_status_q() {  
  79.    rh_status >/dev/null 2>&1  
  80. }  
  81. case "$1" in  
  82.    start)  
  83.        rh_status_q && exit 0  
  84.        $1  
  85.        ;;  
  86.    stop)  
  87.        rh_status_q || exit 0  
  88.        $1  
  89.        ;;  
  90.    restart|configtest)  
  91.        $1  
  92.        ;;  
  93.    reload)  
  94.        rh_status_q || exit 7  
  95.        $1  
  96.        ;;  
  97.    force-reload)  
  98.        force_reload  
  99.         ;;  
  100.    status)  
  101.        rh_status  
  102.        ;;  
  103.    condrestart|try-restart)  
  104.        rh_status_q || exit 0  
  105.             ;;  
  106.    *)  
  107.        echo $"Usage: $0{start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"  
  108.        exit 2  
  109. esac 

而后为此脚本赋予执行权限:

# chmod +x /etc/rc.d/init.d/nginx

添加至服务管理列表,并让其开机自动启动:

# chkconfig --add nginx

# chkconfig nginx on

4,配置Nginx代理

# cat nginx.conf

   
  1. user nginx nginx;  
  2.     worker_processes 1;  
  3.     pid /var/run/nginx/nginx.pid;  
  4.     worker_rlimit_nofile 51200;  
  5.     events  
  6.     {  
  7.     use epoll;  
  8.     worker_connections 51200;  
  9.     }  
  10.     http{  
  11.     include       mime.types;  
  12.     default_type application/octet-stream;  
  13.     server_names_hash_bucket_size 128;  
  14.     client_header_buffer_size 32k;  
  15.     large_client_header_buffers 4 32k;  
  16.     client_max_body_size 8m;  
  17.     sendfile on;  
  18.     tcp_nopush     on;  
  19.     keepalive_timeout 60;  
  20.     tcp_nodelay on;  
  21.     fastcgi_connect_timeout 300;  
  22.     fastcgi_send_timeout 300;  
  23.     fastcgi_read_timeout 300;  
  24.     fastcgi_buffer_size 64k;  
  25.     fastcgi_buffers 4 64k;  
  26.     fastcgi_busy_buffers_size 128k;  
  27.     fastcgi_temp_file_write_size 128k;  
  28.     gzip on;  
  29.     gzip_min_length 1k;  
  30.     gzip_buffers     4 16k;  
  31.     gzip_http_version 1.0;  
  32.     gzip_comp_level 2;  
  33.     gzip_types       text/plain application/x-javascript text/css application/xml;  
  34.     gzip_vary on;  
  35.     upstream backend  
  36.     {  
  37.     ip_hash;  
  38.     server 192.168.1.201:80;  
  39.     server 192.168.1.202:80;  
  40.     }  
  41.     log_format access '$remote_addr - $remote_user [$time_local] "$request" '  
  42.     '$status $body_bytes_sent "$http_referer" '  
  43.     '"$http_user_agent" $http_x_forwarded_for';  
  44.     access_log /var/log/nginx/access.log access;  
  45.     server {  
  46.     listen 80;  
  47.     server_name www.test.com;  
  48.     location / {  
  49.     root /var/www/html ;  
  50.     index index.php index.htm index.html;  
  51.     proxy_redirect off;  
  52.     proxy_set_header Host $host;  
  53.     proxy_set_header X-Real-IP $remote_addr;  
  54.     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  
  55.     proxy_pass http://backend;  
  56.     }  
  57.     location /nginx {  
  58.     access_log off;  
  59.     auth_basic "NginxStatus";  
  60.     }  
  61.     }  

三、安装与配置keepalived

   
  1. # wgethttp://www.keepalived.org/software/keepalived-1.2.16.tar.gz    
  2. # yum -y install libnl-devel  
  3. # ./configure --prefix=/usr/local/keepalived    
  4. # make && make install    
  5. # cp /usr/local/keepalived/sbin/keepalived /usr/sbin/   
  6. # cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/   
  7. # cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/   
  8. # mkdir /etc/keepalived    
  9. # cd /etc/keepalived/  
  10. # vim keepalived.conf 

以上步骤在两台keepalived机器上都需要进行

下面分别是两节点的配置文件

节点一

   
  1. ! Configuration File for keepalived    
  2.      
  3. global_defs {    
  4.    notification_email {    
  5.          ganen2008@126.com #接收警报的email地址,可以添加多个  
  6.    }    
  7.    notification_email_from ganen201405@126.com #发件人地址  
  8.    smtp_connect_timeout 3  #超时时间  
  9.    smtp_server 127.0.0.1  #发送邮件的服务器  
  10.    router_id LVS_DEVEL  #load balancer的标识ID,用于email警报  
  11. }    
  12. vrrp_instance VI_1 {    
  13.     state MASTER  
  14.     interface eth0  
  15.     virtual_router_id 51   
  16.     priority 100    # 权值要比 back 高  
  17.     advert_int 1  
  18.     authentication {    
  19.         auth_type PASS    
  20.         auth_pass 123456  
  21.     }    
  22.     virtual_ipaddress {    
  23.         192.168.1.149 #vip的地址  
  24.   }  
  25. }    
  26. vrrp_instance VI_2 {    
  27.     state BACKUP  
  28.     interface eth0    
  29.     virtual_router_id 52   
  30.     priority 90  
  31.     advert_int 1   
  32.     authentication {    
  33.         auth_type PASS    
  34.         auth_pass 123456   
  35.     }    
  36.     virtual_ipaddress {    
  37.         192.168.1.150  
  38.     }   

节点二

   
  1. ! Configuration File for keepalived  
  2. global_defs {  
  3.    notification_email {  
  4.          ganen2008@126.com  
  5.    }  
  6.    notification_email_from ganen201405@126.com  
  7.    smtp_connect_timeout 3  
  8.    smtp_server 127.0.0.1  
  9.    router_id LVS_DEVEL  
  10. }  
  11. vrrp_instance VI_1 {  
  12.     state BACKUP  
  13.     interface eth1  
  14.     virtual_router_id 51  
  15.     priority 90  
  16.     advert_int 1  
  17.     authentication {  
  18.         auth_type PASS  
  19.         auth_pass 123456  
  20.     }  
  21.     virtual_ipaddress {  
  22.         192.168.1.149  
  23.   }  
  24. }  
  25. vrrp_instance VI_2 {   
  26.     state MASTER  
  27.     interface eth1   
  28.     virtual_router_id 52  
  29.     priority 100  
  30.     advert_int 1  
  31.     authentication {  
  32.         auth_type PASS  
  33.         auth_pass 123456  
  34.     }  
  35.     virtual_ipaddress {  
  36.         192.168.1.150  
  37.     }  

为两节点添加nginx状态监控脚本,由于keepalived本身不能检测到nginx的存活状态,需要借助于第三方脚本来实现,下面是出自余洪春前辈的一个检测脚本,在这里借用一下。

# vim /home/nginx_chk.sh

# chmod +x /home/nginx_chk.sh

   
  1. #!/bin/bash  
  2. while  :  
  3. do  
  4. nginxpid=`ps -C nginx --no-header | wc -l`  
  5.  if [ $nginxpid -eq 0 ];then  
  6.   /usr/local/nginx/sbin/nginx  
  7.   sleep 5  
  8. nginxpid=`ps -C nginx --no-header | wc -l`  
  9.   echo $nginxpid  
  10.     if [ $nginxpid -eq 0 ];then  
  11.  /etc/init.d/keepalived stop  
  12.    fi  
  13.  fi  
  14.  sleep 5  
  15. done 
# chmod +x /home/nginx_chk.sh  后台执行该脚本  # nohup sh /home/nginx_chk.sh &

四、安装web server

这里为了测试我直接使用yum安装两台服务器上的nginx服务。

增加额外资源库

   
  1. # yum -y install yum-priorities  
  2. # rpm -Uvh http://mirrors.yun-idc.com/epel/6/x86_64/epel-release-6-8.noarch.rpm   
  3. # rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm   
  4. # yum -y install nginx  
  5. # /etc/init.d/nginx start 

五、启动测试

首先测试两台WebServer的可用性

Nginx配合keepalived实现双主负载均衡 Nginx配合keepalived实现双主负载均衡

可以看到两台WebServer都运行正常

查看两台keepalived节点的IP情况

Nginx配合keepalived实现双主负载均衡 Nginx配合keepalived实现双主负载均衡

使用两个VIP进行访问

Nginx配合keepalived实现双主负载均衡 Nginx配合keepalived实现双主负载均衡

停掉一台keepalived服务,查看IP

Nginx配合keepalived实现双主负载均衡 Nginx配合keepalived实现双主负载均衡

可以看到VIP已经成功流转到另一节点上,再使用VIP进行访问,依然可以正常访问。

Nginx配合keepalived实现双主负载均衡 Nginx配合keepalived实现双主负载均衡

这时重新启动节点一上的keepalived服务,可以看到属于节点一的VIP又重新回到了节点一上。

Nginx配合keepalived实现双主负载均衡

基本配置到这里就完成了。

博文地址:http://zhangjianjian.blog.51cto.com/2944771/1627995