Nginx 反向代理、负载均衡、页面缓存、URL重写及读写分离详解



原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://freeloda.blog.51cto.com/2033581/1288553


一、前言

       在前面的几篇博文中我们主要讲解了Nginx作为Web服务器知识点,主要的知识点有nginx的理论详解、nginx作为web服务器的操作讲解、nginx作为LNMP架构的讲解,不清楚的博友可以回头看看,在这一篇博客中我们主要讲解, nginx的反向代理、负载均衡、缓存、URL重写以及读写分离详解。好了,下面我们来具体说一说。

二、环境准备

1. 操作系统

  • CentOS 6.4 x86_64

2.软件版本

  • Nginx 1.4.2

3.实验拓扑

注,实验拓扑见下文。

4.安装yum源

1
2
3
[root@nginx ~] # rpm -ivh http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
[root@web1 ~] # rpm -ivh http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
[root@web2 ~] # rpm -ivh http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm

5.各节点时间同步

1
2
3
[root@nginx ~] # ntpdate 202.120.2.101
[root@web1 ~] # ntpdate 202.120.2.101
[root@web2 ~] # ntpdate 202.120.2.101

6.关闭防火墙与SELinux

1
2
3
4
5
6
7
8
9
10
11
12
[root@nginx ~] # service iptables stop
[root@nginx ~] # chkconfig iptables off 
[root@nginx ~] # getenforce 
Disabled
[root@web1 ~] # service iptables stop
[root@web1 ~] # chkconfig iptables off 
[root@web1 ~] # getenforce 
Disabled
[root@web2 ~] # service iptables stop
[root@web2 ~] # chkconfig iptables off 
[root@web2 ~] # getenforce 
Disabled

三、安装Nginx

1.解压

1
[root@nginx src] # tar xf nginx-1.4.2.tar.gz

2.新建nginx用户与组

1
2
3
4
[root@nginx src] # groupadd -g 108  -r nginx
[root@nginx src] # useradd -u 108 -r -g 108 nginx 
[root@nginx src] # id nginx 
uid=108(nginx) gid=108(nginx) 组=108(nginx)

3.准备编译配置文件

1
2
[root@nginx src] # yum install -y pcre-devel openssl-devel
[root@nginx nginx-1.4.2] # ./configure   --prefix=/usr   --sbin-path=/usr/sbin/nginx   --conf-path=/etc/nginx/nginx.conf   --error-log-path=/var/log/nginx/error.log   --http-log-path=/var/log/nginx/access.log   --pid-path=/var/run/nginx/nginx.pid    --lock-path=/var/lock/nginx.lock   --user=nginx   --group=nginx   --with-http_ssl_module   --with-http_flv_module   --with-http_stub_status_module   --with-http_gzip_static_module   --http-client-body-temp-path=/var/tmp/nginx/client/   --http-proxy-temp-path=/var/tmp/nginx/proxy/   --http-fastcgi-temp-path=/var/tmp/nginx/fcgi/   --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi   --http-scgi-temp-path=/var/tmp/nginx/scgi   --with-pcre

4.编译并安装

1
[root@nginx nginx-1.4.2] # make && make install

5.为nginx提供SysV init脚本

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

6.为此脚本赋予执行权限

1
[root@nginx ~] # chmod +x /etc/init.d/nginx

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

1
2
3
4
[root@nginx ~] # chkconfig --add nginx
[root@nginx ~] # chkconfig nginx on 
[root@nginx ~] # chkconfig nginx --list 
nginx              0:关闭    1:关闭    2:启用    3:启用    4:启用    5:启用    6:关闭

8.启动nginx

1
2
[root@nginx ~] # service nginx start
正在启动 nginx:                                           [确定]

9.查看一下端口

1
2
[root@nginx ~] # netstat -ntlp | grep :80
tcp        0      0 0.0.0.0:80                  0.0.0.0:*                   LISTEN      3889 /nginx

10.测试一下

Nginx 反向代理、负载均衡、页面缓存、URL重写及读写分离详解_第1张图片

好了,Nginx安装与配置就到这里,下面我们来说一说Nginx的反向代理。

四、Nginx之反向代理

在配置nginx反向代理之间我们得先准备两台测试服务器,Web1与Web2。

1.安装httpd

1
2
[root@web1 ~] # yum install -y httpd
[root@web2 ~] # yum install -y httpd

2.提供测试页面

1
2
[root@web1 ~] # echo "<h1>web1.test.com</h1>" > /var/www/html/index.html
[root@web2 ~] # echo "<h1>web2.test.com</h1>" > /var/www/html/index.html

3.启动httpd服务

1
2
3
4
[root@web1 ~] # service httpd start
正在启动 httpd:                                           [确定]
[root@web2 ~] # service httpd start
正在启动 httpd:                                           [确定]

4.测试一下

Nginx 反向代理、负载均衡、页面缓存、URL重写及读写分离详解_第2张图片

Nginx 反向代理、负载均衡、页面缓存、URL重写及读写分离详解_第3张图片

5.简单说一下,正向代理与反向代理

(1).正向代理的概念

       正向代理,也就是传说中的代理,他的工作原理就像一个跳板,简单的说,我是一个用户,我访问不了某网站,但是我能访问一个代理服务器,这个代理服务器呢,他能访问那个我不能访问的网站,于是我先连上代理服务器,告诉他我需要那个无法访问网站的内容,代理服务器去取回来,然后返回给我。从网站的角度,只在代理服务器来取内容的时候有一次记录,有时候并不知道是用户的请求,也隐藏了用户的资料,这取决于代理告不告诉网站。

       结论就是,正向代理 是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。客户端必须要进行一些特别的设置才能使用正向代理。

(2).反向代理的概念

继续举例:    
       例用户访问 
http://www.test.com/readme,但www.test.com上并不存在readme页面,他是偷偷从另外一台服务器上取回来,然后作为自己的内容返回用户,但用户并不知情。这里所提到的 www.test.com 这个域名对应的服务器就设置了反向代理功能。

       结论就是,反向代理正好相反,对于客户端而言它就像是原始服务器,并且客户端不需要进行任何特别的设置。客户端向反向代理的命名空间(name-space)中的内容发送普通请求,接着反向代理将判断向何处(原始服务器)转交请求,并将获得的内容返回给客户端,就像这些内容原本就是它自己的一样。

(3).两者区别

用途上来讲:

       正向代理的典型用途是为在防火墙内的局域网客户端提供访问Internet的途径。正向代理还可以使用缓冲特性减少网络使用率。反向代理的典型用途是将防火墙后面的服务器提供给Internet用户访问。反向代理还可以为后端的多台服务器提供负载平衡,或为后端较慢的服务器提供缓冲服务。另外,反向代理还可以启用高级URL策略和管理技术,从而使处于不同web服务器系统的web页面同时存在于同一个URL空间下。

安全性来讲:

       正向代理允许客户端通过它访问任意网站并且隐藏客户端自身,因此你必须采取安全措施以确保仅为经过授权的客户端提供服务。反向代理对外都是透明的,访问者并不知道自己访问的是一个代理。

6.nginx 代理模块

http 代理官方中文文档http://www.howtocn.org/nginx:nginx%E6%A8%A1%E5%9D%97%E5%8F%82%E8%80%83%E6%89%8B%E5%86%8C%E4%B8%AD%E6%96%87%E7%89%88:standardhttpmodules:httpproxy

说明:代理模块的指令有很多我这里只讲解重要的proxy_pass,想了解更多代理指令请参考官方中文文档。

这个模块可以转发请求到其他的服务器。HTTP/1.0无法使用keepalive(后端服务器将为每个请求创建并且删除连接)。nginx为浏览器发送HTTP/1.1并为后端服务器发送HTTP/1.0,这样浏览器就可以为浏览器处理keepalive。     
如下例:

1
2
3
4
location / {
   proxy_pass        http: //localhost :8000;
   proxy_set_header  X-Real-IP  $remote_addr;
}

注意,当使用http proxy模块(甚至FastCGI),所有的连接请求在发送到后端服务器之前nginx将缓存它们,因此,在测量从后端传送的数据时,它的进度显示可能不正确。

实验拓扑:

Nginx 反向代理、负载均衡、页面缓存、URL重写及读写分离详解_第4张图片

7.配置http反向代理

1
2
3
4
5
6
[root@nginx ~] # cd /etc/nginx/
[root@nginx nginx] # cp nginx.conf nginx.conf.bak #备份一个原配置文件
[root@nginx nginx] # vim nginx.conf
location / {
                proxy_pass      http: //192 .168.18.201;
        }

指令说明:proxy_pass

语法:proxy_pass URL
默认值:no       
使用字段:location, location中的if字段       
这个指令设置被代理服务器的地址和被映射的URI,地址可以使用主机名或IP加端口号的形式,例如:
proxy_pass http://localhost:8000/uri/;

8.重新加载一下配置文件

1
2
3
4
[root@nginx ~] # service nginx reload
nginx: the configuration  file  /etc/nginx/nginx .conf syntax is ok
nginx: configuration  file  /etc/nginx/nginx .conf  test  is successful
重新载入 nginx:                                           [确定]

9.测试一下

Nginx 反向代理、负载均衡、页面缓存、URL重写及读写分离详解_第5张图片

注,大家可以看到,当我们访问192.168.18.208时,被代理重新定向到Web1上。

10.查看一下Web服务器日志

1
2
3
4
5
6
7
8
9
10
11
[root@web1 ~] # tail /var/log/httpd/access_log
192.168.18.208 - - [04 /Sep/2013 :00:14:20 +0800]  "GET /favicon.ico HTTP/1.0"  404 289  "-"  "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36"
192.168.18.208 - - [04 /Sep/2013 :00:14:20 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36"
192.168.18.208 - - [04 /Sep/2013 :00:14:20 +0800]  "GET /favicon.ico HTTP/1.0"  404 289  "-"  "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36"
192.168.18.138 - - [04 /Sep/2013 :00:14:45 +0800]  "GET / HTTP/1.1"  200 23  "-"  "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36"
192.168.18.138 - - [04 /Sep/2013 :00:14:48 +0800]  "GET /favicon.ico HTTP/1.1"  404 289  "-"  "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36"
192.168.18.208 - - [04 /Sep/2013 :00:14:55 +0800]  "GET /favicon.ico HTTP/1.0"  404 289  "-"  "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36"
192.168.18.208 - - [04 /Sep/2013 :00:15:05 +0800]  "GET /favicon.ico HTTP/1.0"  404 289  "-"  "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36"
192.168.18.208 - - [04 /Sep/2013 :00:15:13 +0800]  "GET /favicon.ico HTTP/1.0"  404 289  "-"  "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36"
192.168.18.208 - - [04 /Sep/2013 :00:15:16 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36"
192.168.18.208 - - [04 /Sep/2013 :00:15:16 +0800]  "GET /favicon.ico HTTP/1.0"  404 289  "-"  "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36"

注,大家可以看到我们这里的客户的IP全是,nginx代理服务器的IP,并不是真实客户端的IP。下面我们修改一下,让日志的IP显示真实的客户端的IP。

11.修改nginx配置文件

1
2
3
4
location / {
         proxy_pass      http: //192 .168.18.201;
         proxy_set_header  X-Real-IP  $remote_addr;  #加上这一行
}

指令说明proxy_set_header

语法:proxy_set_header header value 
默认值: Host and Connection 
使用字段:http, server, location 
这个指令允许将发送到被代理服务器的请求头重新定义或者增加一些字段。这个值可以是一个文本,变量或者它们的组合。proxy_set_header在指定的字段中没有定义时会从它的上级字段继承。

12.重新加载一下配置文件

1
2
3
4
[root@nginx ~] # service nginx reload
nginx: the configuration  file  /etc/nginx/nginx .conf syntax is ok
nginx: configuration  file  /etc/nginx/nginx .conf  test  is successful
重新载入 nginx:                                           [确定]

13.测试并查看日志

1
2
3
4
5
6
7
8
9
10
11
[root@web1 ~] # tail /var/log/httpd/access_log
192.168.18.208 - - [03 /Sep/2013 :16:26:18 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
192.168.18.208 - - [03 /Sep/2013 :16:26:18 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
192.168.18.208 - - [03 /Sep/2013 :16:26:18 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
192.168.18.208 - - [03 /Sep/2013 :16:26:18 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
192.168.18.208 - - [03 /Sep/2013 :16:26:18 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
192.168.18.208 - - [03 /Sep/2013 :16:26:18 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
192.168.18.208 - - [03 /Sep/2013 :16:26:18 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
192.168.18.208 - - [03 /Sep/2013 :16:26:18 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
192.168.18.208 - - [03 /Sep/2013 :16:26:18 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
192.168.18.208 - - [03 /Sep/2013 :16:26:18 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"

注,大家可以看到日志记录的还是代理的IP,没有显示真实客户端的IP,为什么呢?我们来看一下httpd的配置文件。

14.查看并修改httpd配置文件

[root@web1 ~]# vim /etc/httpd/conf/httpd.conf

t5

注,大家可以这里记录日志的参数还是%h,下面我们修改一下参数。

t6

注,这是修改后的参数,将h%修改为%{X-Real-IP}i,好的下面我们再来测试一下。

15.重启并测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@web1 ~] # service httpd restart
停止 httpd:                                               [确定]
正在启动 httpd:                                           [确定]
[root@web1 ~] # tail /var/log/httpd/access_log
192.168.18.138 - - [03 /Sep/2013 :17:09:14 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
192.168.18.138 - - [03 /Sep/2013 :17:09:14 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
192.168.18.138 - - [03 /Sep/2013 :17:09:15 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
192.168.18.138 - - [03 /Sep/2013 :17:09:15 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
192.168.18.138 - - [03 /Sep/2013 :17:09:15 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
192.168.18.138 - - [03 /Sep/2013 :17:09:15 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
192.168.18.138 - - [03 /Sep/2013 :17:09:15 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
192.168.18.138 - - [03 /Sep/2013 :17:09:15 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
192.168.18.138 - - [03 /Sep/2013 :17:09:15 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
192.168.18.138 - - [03 /Sep/2013 :17:09:15 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"

注,大家可以看到现在的日志里记录的IP地址就是真实的客户端地址了。好了,到这里Nginx代理后端一台服务器就演示到这里,下面我们继续说。

五、Nginx之负载均衡

注,大家可以看到,由于我们网站是发展初期,nginx只代理了后端一台服务器,但由于我们网站名气大涨访问的人越来越多一台服务器实在是顶不住,于是我们加了多台服务器,那么多台服务器又怎么配置代理呢,我们这里以两台服务器为案例,为大家做演示。

1.upstream 负载均衡模块说明

案例:

下面设定负载均衡的服务器列表。

1
2
3
4
5
6
7
8
9
10
11
12
upstream  test .net{
ip_hash;
server 192.168.10.13:80;
server 192.168.10.14:80  down;
server 192.168.10.15:8009  max_fails=3  fail_timeout=20s;
server 192.168.10.16:8080;
}
server {
   location / {
     proxy_pass  http: //test .net;
   }
}

       upstream是Nginx的HTTP Upstream模块,这个模块通过一个简单的调度算法来实现客户端IP到后端服务器的负载均衡。在上面的设定中,通过upstream指令指定了一个负载均衡器的名称test.net。这个名称可以任意指定,在后面需要用到的地方直接调用即可。

2.upstream 支持的负载均衡算法

Nginx的负载均衡模块目前支持4种调度算法,下面进行分别介绍,其中后两项属于第三方调度算法。  

  • 轮询(默认)。每个请求按时间顺序逐一分配到不同的后端服务器,如果后端某台服务器宕机,故障系统被自动剔除,使用户访问不受影响。Weight 指定轮询权值,Weight值越大,分配到的访问机率越高,主要用于后端每个服务器性能不均的情况下。

  • ip_hash。每个请求按访问IP的hash结果分配,这样来自同一个IP的访客固定访问一个后端服务器,有效解决了动态网页存在的session共享问题。

  • fair。这是比上面两个更加智能的负载均衡算法。此种算法可以依据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间来分配请求,响应时间短的优先分配。Nginx本身是不支持fair的,如果需要使用这种调度算法,必须下载Nginx的upstream_fair模块。

  • url_hash。此方法按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,可以进一步提高后端缓存服务器的效率。Nginx本身是不支持url_hash的,如果需要使用这种调度算法,必须安装Nginx 的hash软件包。

3.upstream 支持的状态参数

在HTTP Upstream模块中,可以通过server指令指定后端服务器的IP地址和端口,同时还可以设定每个后端服务器在负载均衡调度中的状态。常用的状态有:      

  • down,表示当前的server暂时不参与负载均衡。

  • backup,预留的备份机器。当其他所有的非backup机器出现故障或者忙的时候,才会请求backup机器,因此这台机器的压力最轻。

  • max_fails,允许请求失败的次数,默认为1。当超过最大次数时,返回proxy_next_upstream 模块定义的错误。

  • fail_timeout,在经历了max_fails次失败后,暂停服务的时间。max_fails可以和fail_timeout一起使用。

注,当负载调度算法为ip_hash时,后端服务器在负载均衡调度中的状态不能是weight和backup。

4.实验拓扑

Nginx 反向代理、负载均衡、页面缓存、URL重写及读写分离详解_第6张图片

5.配置nginx负载均衡

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@nginx ~] # vim /etc/nginx/nginx.conf
upstream webservers {
       server 192.168.18.201 weight=1;
       server 192.168.18.202 weight=1;
   }
   server {
       listen       80;
       server_name  localhost;
       #charset koi8-r;
       #access_log  logs/host.access.log  main;
       location / {
               proxy_pass      http: //webservers ;
               proxy_set_header  X-Real-IP  $remote_addr;
       }
}

注,upstream是定义在server{ }之外的,不能定义在server{ }内部。定义好upstream之后,用proxy_pass引用一下即可。

6.重新加载一下配置文件

1
2
3
4
[root@nginx ~] # service nginx reload
nginx: the configuration  file  /etc/nginx/nginx .conf syntax is ok
nginx: configuration  file  /etc/nginx/nginx .conf  test  is successful
重新载入 nginx:                                           [确定]

7.测试一下

Nginx 反向代理、负载均衡、页面缓存、URL重写及读写分离详解_第7张图片

Nginx 反向代理、负载均衡、页面缓存、URL重写及读写分离详解_第8张图片

注,大家可以不断的刷新浏览的内容,可以发现web1与web2是交替出现的,达到了负载均衡的效果。

8.查看一下Web访问服务器日志

Web1:

1
2
3
4
5
6
7
8
9
10
11
[root@web1 ~] # tail /var/log/httpd/access_log
192.168.18.138 - - [04 /Sep/2013 :09:41:58 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
192.168.18.138 - - [04 /Sep/2013 :09:41:58 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
192.168.18.138 - - [04 /Sep/2013 :09:41:59 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
192.168.18.138 - - [04 /Sep/2013 :09:41:59 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
192.168.18.138 - - [04 /Sep/2013 :09:42:00 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
192.168.18.138 - - [04 /Sep/2013 :09:42:00 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
192.168.18.138 - - [04 /Sep/2013 :09:42:00 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
192.168.18.138 - - [04 /Sep/2013 :09:44:21 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
192.168.18.138 - - [04 /Sep/2013 :09:44:22 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
192.168.18.138 - - [04 /Sep/2013 :09:44:22 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"

Web2:

先修改一下,Web服务器记录日志的格式。

1
2
3
4
5
[root@web2 ~] # vim /etc/httpd/conf/httpd.conf
LogFormat  "%{X-Real-IP}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\""  combined
[root@web2 ~] # service httpd restart
停止 httpd:                                               [确定]
正在启动 httpd:                                           [确定]

接着,再访问多次,继续查看日志。

1
2
3
4
5
6
7
8
9
10
11
[root@web2 ~] # tail /var/log/httpd/access_log
192.168.18.138 - - [04 /Sep/2013 :09:50:28 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
192.168.18.138 - - [04 /Sep/2013 :09:50:28 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
192.168.18.138 - - [04 /Sep/2013 :09:50:28 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
192.168.18.138 - - [04 /Sep/2013 :09:50:28 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
192.168.18.138 - - [04 /Sep/2013 :09:50:28 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
192.168.18.138 - - [04 /Sep/2013 :09:50:28 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
192.168.18.138 - - [04 /Sep/2013 :09:50:28 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
192.168.18.138 - - [04 /Sep/2013 :09:50:28 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
192.168.18.138 - - [04 /Sep/2013 :09:50:29 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
192.168.18.138 - - [04 /Sep/2013 :09:50:29 +0800]  "GET / HTTP/1.0"  200 23  "-"  "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"

注,大家可以看到,两台服务器日志都记录是192.168.18.138访问的日志,也说明了负载均衡配置成功。

9.配置nginx进行健康状态检查

  • max_fails,允许请求失败的次数,默认为1。当超过最大次数时,返回proxy_next_upstream 模块定义的错误。

  • fail_timeout,在经历了max_fails次失败后,暂停服务的时间。max_fails可以和fail_timeout一起使用,进行健康状态检查。

1
2
3
4
5
[root@nginx ~] # vim /etc/nginx/nginx.conf
upstream webservers {
         server 192.168.18.201 weight=1 max_fails=2 fail_timeout=2;
         server 192.168.18.202 weight=1 max_fails=2 fail_timeout=2;
     }

10.重新加载一下配置文件

1
2
3
4
[root@nginx ~] # service nginx reload
nginx: the configuration  file  /etc/nginx/nginx .conf syntax is ok
nginx: configuration  file  /etc/nginx/nginx .conf  test  is successful
重新载入 nginx:                                           [确定]

11.停止服务器并测试

1
2
3
先停止Web1,进行测试。
[root@web1 ~] # service httpd stop
停止 httpd:                             &n

你可能感兴趣的:(nginx,url重写,Nginx代理)