本文档主要介绍CentOS6.9系统用Nginx服务实现负载均衡功能


基本流程:

  1. Nginx负载均衡的环境准备

  2. Nginx实现一个简单的负载均衡

  3. Nginx负载均衡配置实战

  4. Nginx负载均衡监测节点状态




步骤一:Nginx负载均衡的环境准备


1.硬件准备(准备四台VM虚拟机或物理服务器,两台做负载均衡,两台做web,如下表所示)

                          hostname                                 IP                              说明与介绍
                           fzMaster                         192.168.1.59                       Nginx主负载均衡器
                           fzBackup                        192.168.1.58                       Nginx备负载均衡器
                           web01                        192.168.1.23                          web01服务器
                           web02                        192.168.1.25                          web02服务器


2.系统和软件准备

系统:

[root@fzMaster ~]# cat /etc/redhat-release 

CentOS release 6.9 (Final)


[root@fzMaster ~]# uname -r

2.6.32-696.20.1.el6.x86_64


软件: nginx-1.6.3.tar.gz (下载链接:http://nginx.org/download/nginx-1.6.3.tar.gz;其它版本只需改存在的版本号即可)


3.四台服务器上都要源码安装nginx

1)yum安装依赖软件包

配置yum源请参考  https://blog.51cto.com/13707680/2104644

yum install openssl openssl-devel pcre pcre-devel -y

rpm -qa openssl openssl-devel pcre pcre-devel (命令执行完后检查,这是运维专业的规范)


2)源码安装Nginx,命令集如下:

mkdir -p /home/ywxi/tools

cd /home/ywxi/tools/

wget -q http://nginx.org/download/nginx-1.6.3.tar.gz

ls -l nginx-1.6.3.tar.gz

useradd nginx -s /sbin/nologin -M

tar xf nginx-1.6.3.tar.gz

cd nginx-1.6.3

 ./configure --user=nginx --group=nginx --prefix=/application/nginx-1.6.3 --with-http_stub_status_module --with-http_ssl_module

make 

make install

echo $?

ln -s /application/nginx-1.6.3/ /application/nginx

ll /application/nginx

ls -l /application/nginx/

/application/nginx/sbin/nginx -t

/application/nginx/sbin/nginx

lsof -i :80

netstat -tnlp | grep 80


3)配置用于测试的web服务(web01和web02都要配置)

[root@web01 conf]# cat nginx.conf

worker_processes  1;

events {

    worker_connections  1024;

}

http {

    include       mime.types;

    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request"'

                      '$status $body_bytes_sent "$http_referer" '

                      '"$http_user_agent" "$http_x_forwarded_for"';

    server {

        listen       80;

        server_name  ywxi.com;

        location / {

            root   html/ywxi;

            index  index.html index.htm;

        }

        access_log logs/access_ywxi.log main;

}

    server {

        listen       80;

        server_name  back.com;

        location / {

            root   html/back;

            index  index.html index.htm;

        }

        access_log logs/access_back.log main;

}

}


3)向nginx代码目录下放置数据,用来测试

mkdir /application/nginx/html/{ywxi,back}    (两台web都执行)


web01这台主机上的操作

echo "192.168.1.23 web01 back" > /application/nginx/html/back/index.html

echo "192.168.1.23 web01 ywxi" > /application/nginx/html/ywxi/index.html


web02这台主机上的操作

echo "192.168.1.25 web02 back" > /application/nginx/html/back/index.html

echo "192.168.1.25 web02 ywxi" > /application/nginx/html/ywxi/index.html


添加好后用fzMaster这台服务器测试

[root@fzMaster ~]# tail -2 /etc/hosts

192.168.1.25  ywxi.com

192.168.1.23  back.com

[root@fzMaster ~]# curl ywxi.com

192.168.1.25 web02 ywxi

[root@fzMaster ~]# curl back.com    

192.168.1.23 web01 back

通过上面这些配置就实现了两台Web服务器基于域名的虚拟主机配置了。




步骤二:Nginx实现一个简单的负载均衡

                                                             

                                                                                         第一台Nginx负载均衡器的准备信息

                             hostname                                      IP                                  说明与介绍
                              fzMaster                              192.168.1.59                           Nginx主负载均衡器


下面进行一个简单的Nginx负载均衡配置,代理ywxi.com服务,节点为web01和web02。nginx.conf配置文件内容如下:

worker_processes  1;

events {

    worker_connections  1024;

}

http {

    include       mime.types;

    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    upstream www_server_pools {                       #这里是定义web服务器池,包含了23和25两个web节点

            server 192.168.1.23:80 weight=1;

            server 192.168.1.25:80 weight=1;

    }

    server {                                                           #定义虚拟主机

        listen       80;

        server_name  ywxi.com;

        location / {

        proxy_pass http://www_server_pools;      #访问ywxi.com,请求会发送给www_server_pools里面的节点

        }

    }

}


报错:[root@fzMaster conf]# nginx -s reload

nginx: [error] invalid PID number "" in "/application/nginx-1.6.3/logs/nginx.pid"

解决:ps -ef | grep nginx|head -1 |awk '{print $2}' > /application/nginx-1.6.3/logs/nginx.pid


netstat -tnlp |grep nginx

然后,检查负载均衡测试结果。用linux作为客户端来测试:

[root@fzMaster conf]# tail -1 /etc/hosts

192.168.1.59  ywxi.com   #192.168.1.59为主负载均衡器的IP

[root@fzMaster conf]# curl ywxi.com 

192.168.1.23 web01 ywxi

[root@fzMaster conf]# curl ywxi.com 

192.168.1.25 web02 ywxi

[root@fzMaster conf]# curl ywxi.com 

192.168.1.23 web01 ywxi

[root@fzMaster conf]# curl ywxi.com 

192.168.1.25 web02 ywxi


可以看见请求都是一比一的分配,现在我们假设宕掉两台web服务器:

[root@fzMaster conf]# curl ywxi.com 

502 Bad Gateway

502 Bad Gateway


nginx/1.6.3

Nginx代理下面没有了节点,因为Nginx向用户报告了502错误。


如果只宕掉一台web,代理就不会去访问宕机的web服务,只会访问正常的web服务器

[root@fzMaster conf]# curl ywxi.com 

192.168.1.23 web01 ywxi

[root@fzMaster conf]# curl ywxi.com 

192.168.1.25 web02 ywxi

[root@fzMaster conf]# curl ywxi.com 

192.168.1.25 web02 ywxi

[root@fzMaster conf]# curl ywxi.com 

192.168.1.25 web02 ywxi

到这里一台简单的Ngxin负载均衡器就搭建好了。




步骤三:Nginx负载均衡配置实战

                                                                                                           

                                                                                     Nginx  Web 服务器节点信息

                             hostname                                      IP                                  说明与介绍
                              web01                             192.168.1.23                              web01服务器
                              web02                             192.168.1.25                              web02服务器

前文已经配置好两台web的nginx的配置文件

1)创建站点目录及对应测试文件,命令如下:

[root@web01 conf]# for n in ywxi back;do cd /application/nginx/html/;mkdir -p $n;echo "$n.com23" >$n/index.html;done

[root@web02 html]# for n in ywxi back;do cd /application/nginx/html/;mkdir -p $n;echo "$n.com25" >$n/index.html;done

[root@web01 html]# cat ywxi/index.html 

ywxi.com23

[root@web01 html]# cat back/index.html     

back.com23


2)两台都做同样的操作:

ln -s /application/nginx/sbin/nginx /bin/nginx   

[root@web01 html]# nginx -t

nginx: the configuration file /application/nginx-1.6.3/conf/nginx.conf syntax is ok

nginx: configuration file /application/nginx-1.6.3/conf/nginx.conf test is successful

[root@web01 html]# nginx -s reload

[root@web01 html]# netstat -tnlp | grep 80

tcp        0      0 0.0.0.0:80                  0.0.0.0:*                   LISTEN      12950/nginx  


3)把域名加入hosts解析

[root@web01 html]# echo "192.168.1.23 ywxi.com " >> /etc/hosts  

[root@web01 html]# echo "192.168.1.23 back.com " >> /etc/hosts 

[root@web01 html]# tail -2 /etc/hosts

192.168.1.23 ywxi.com 

192.168.1.23 back.com 

[root@web02 html]# echo "192.168.1.25 ywxi.com " >> /etc/hosts   

[root@web02 html]# echo "192.168.1.25 back.com " >> /etc/hosts 

[root@web02 html]# tail -2 /etc/hosts

192.168.1.25 ywxi.com 

192.168.1.25 back.com

web01测试:

[root@web01 html]# curl ywxi.com

ywxi.com23

[root@web01 html]# curl back.com    

back.com23

web02测试:

[root@web02 back]# curl back.com          

back.com25

[root@web02 back]# curl ywxi.com          

ywxi.com25

到这里,搭建配置虚拟主机就成功了。


4)Nginx负载均衡实践

主Nginx负载服务器配置如下:

[root@fzMaster conf]# cat nginx.conf

worker_processes  1;

events {

    worker_connections  1024;

}

http {

    include       mime.types;

    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    upstream www_server_pools {                       #这里是定义web服务器池,包含了23和25两个web节点

            server 192.168.1.23:80 weight=1;

            server 192.168.1.25:80 weight=1;

    }

    server {                                                           #定义虚拟主机

        listen       80;

        server_name  back.com;

        location / {

        proxy_pass http://www_server_pools;      #访问ywxi.com,请求会发送给www_server_pools里面的节点

        }

    }

}

配置hosts解析到代理的IP上,然后重新加载下服务,访问测试:

[root@fzMaster conf]# tail -2 /etc/hosts

192.168.1.59  ywxi.com

192.168.1.59  back.com

[root@fzMaster conf]# nginx -s reload

[root@fzMaster conf]# curl back.com

ywxi.com23

[root@fzMaster conf]# curl back.com     

ywxi.com25

从测试结果来看,已经实现了反向代理、负载均衡功能,但是有一个特殊问题,出来的不是带back.com的内容,而是ywxi.com的内容。(提示:这里代理了多个虚拟主机)

解决:

加一行配置即可   proxy_set_header Host $host;

[root@fzMaster conf]# cat nginx.conf

worker_processes  1;

events {

    worker_connections  1024;

}

http {

    include       mime.types;

    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    upstream www_server_pools {      

            server 192.168.1.23 weight=1;

            server 192.168.1.25 weight=1;

    }

    server {

        listen       80;

        server_name  back.com;

        location / {

        proxy_pass http://www_server_pools;

        proxy_set_header Host $host;       #在代理向后端服务器发送的http请求头中加入hosts字段信息,用于当后端服务器配置有多个虚拟主机时,可以识别代理的是哪个虚拟主机。这是节点服务器多虚拟主机时的关键配置

        }

    }

}


重新加载Nginx服务,并用curl测试检查下,结果如下:

[root@fzMaster conf]# nginx -s reload

[root@fzMaster conf]# curl back.com

back.com23

[root@fzMaster conf]# curl back.com

back.com25

可以看到这次访问的结果与访问的域名就完全对应上了,这样代理多虚拟主机的节点服务器就正常了。


5)经过反向代理后的节点服务器记录用户真实IP实战


proxy_set_header   X-Forwarded-For  $remote_addr;   #在代理向后端服务器发送的http请求头中加入X-Forwarded-For字段信息,用于后端服务器程序,日志等接收记录真实用户的IP,而不是代理服务器的IP。 这个地方对应web01和web02的Nginx配置文件中"$http_x_forwarded_for"'日志参数

配置如下:

[root@fzMaster conf]# cat nginx.conf

worker_processes  1;

events {

    worker_connections  1024;

}

http {

    include       mime.types;

    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    upstream www_server_pools {      

            server 192.168.1.23 weight=1;

            server 192.168.1.25 weight=1;

    }

    server {

        listen       80;

        server_name  back.com;

        location / {

        proxy_pass http://www_server_pools;

        proxy_set_header Host $host;

        proxy_set_header   X-Forwarded-For  $remote_addr;

        }

    }

}

配置了日志参数后,用客户端192.168.1.10测试访问:

[root@web01 conf]# tail -2  /application/nginx/logs/access_back.log 

192.168.1.59 - - [24/Apr/2018:16:05:15 +0800] "GET / HTTP/1.0"200 11 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36" "192.168.1.10"

192.168.1.59 - - [24/Apr/2018:16:05:16 +0800] "GET / HTTP/1.0"200 11 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36" "192.168.1.10"


192.168.1.59为反向代理的IP,192.168.1.10为客户端的真实IP。到这里,Nginx负载均衡配置实战已经完成了。




步骤四:Nginx负载均衡监测节点状态

   Tengine(Nginx的分支)模块nginx_upstream_check_module,用于提供主动式后端服务器健康检查。通过它可以检测后端realserver的健康状态,如果后端realserver不可用,则所有请求就不会转发到该节点上。我们这里用Nginx打补丁的方式将该模块添加到Nginx中。

  https://codeload.github.com/yaoweibin/nginx_upstream_check_module/zip/master   #模块下载地址

1)安装nginx_upstream_check_module模块。

[root@fzMaster conf]# nginx -v 

nginx version: nginx/1.6.3


命令集如下:

cd /home/ywxi/tools/

unzip nginx_upstream_check_module-master.zip

patch -p1 < ../nginx_upstream_check_module-master/check_1.5.12+.patch

cd nginx-1.6.3

./configure --user=nginx --group=nginx --prefix=/application/nginx-1.6.3 --with-http_stub_status_module --with-http_ssl_module --add-module=../nginx_upstream_check_module-master

make    #如果是新装的nginx接下来需要make install ,这个是给已经安装的nginx系统打监控补丁就不需要make install了。make的作用就是重新生成Nginx二进制启动命令而已

mv /application/nginx/sbin/nginx{,.ori}

cp ./objs/nginx /application/nginx/sbin/

nginx -t


[root@fzMaster nginx-1.6.3]# nginx -V

nginx version: nginx/1.6.3

built by gcc 4.4.7 20120313 (Red Hat 4.4.7-18) (GCC) 

TLS SNI support enabled

configure arguments: --user=nginx --group=nginx --prefix=/application/nginx-1.6.3 --with-http_stub_status_module --with-http_ssl_module --add-module=../nginx_upstream_check_module-master


2)配置Nginx健康检查,配置文件如下:

worker_processes  1;

events {

    worker_connections  1024;

}

http {

    include       mime.types;

    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    upstream www_server_pools {      

            server 192.168.1.23:80 weight=1;

            server 192.168.1.25:80 weight=1;

            check interval=3000 rise=2 fall=5 timeout=1000 type=http;

    }

    server {

        listen       80;

        server_name  back.com;

        location / {

        proxy_pass http://www_server_pools;

        proxy_set_header Host $host;

        proxy_set_header   X-Forwarded-For  $remote_addr;

        }

        location /status {

        check_status;

        access_log off;

            }   

        } 

}

[root@fzMaster conf]# nginx -s stop #此处必须重启,重新加载不生效

[root@fzMaster conf]# nginx


访问http://192.168.1.59/status页面如下。这是正常状态下Nginx节点健康检查状态

Nginx反向代理和负载均衡应用实战_第1张图片


[root@web01 conf]# nginx -s stop  #假设宕掉一台web01

访问http://192.168.1.59/status页面如下。这是不正常状态下Nginx节点健康检查状态

Nginx反向代理和负载均衡应用实战_第2张图片

到这里本文章就完成了。