Nginx 反向代理、負載均衡、頁面緩存、URL重寫及讀寫分離詳解【轉】

原文:http://freeloda.blog.51cto.com/2033581/1288553html

大綱前端

1、前言nginx

2、環境準備web

3、安裝與配置Nginx正則表達式

4、Nginx之反向代理算法

5、Nginx之負載均衡apache

6、Nginx之頁面緩存vim

7、Nginx之URL重寫 後端

8、Nginx之讀寫分離xcode

注,操做系統爲 CentOS 6.4 x86_64 , Nginx 是版本是最新版的1.4.2,因此實驗用到的軟件請點擊這裏下載:http://yunpan.cn/QXIgqMmVmuZrm

 

1、前言

       在前面的幾篇博文中咱們主要講解了Nginx做爲Web服務器知識點,主要的知識點有nginx的理論詳解、nginx做爲web服務器的操做講解、 nginx做爲LNMP架構的講解,不清楚的博友能夠回頭看看,在這一篇博客中咱們主要講解, nginx的反向代理、負載均衡、緩存、URL重寫以及讀寫分離詳解。好了,下面咱們來具體說一說。

2、環境準備

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

3、安裝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.測試一下

t1

好了,Nginx安裝與配置就到這裏,下面咱們來講一說Nginx的反向代理。

4、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.測試一下

t2

t3

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將緩存它們,所以,在測量從後端傳送的數據時,它的進度顯示可能不正確。

實驗拓撲:

nginx4

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.測試一下

t4

注,你們能夠看到,當咱們訪問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代理後端一臺服務器就演示到這裏,下面咱們繼續說。

5、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.實驗拓撲

nginx3

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.測試一下

t7

t8

注,你們能夠不斷的刷新瀏覽的內容,能夠發現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:                                               [肯定]

t8

注,你們能夠看到,如今只能訪問Web2,再從新啓動Web1,再次訪問一下。

1
2
[root@web1 ~] # service httpd start
正在啓動 httpd:                                           [肯定]

t7

t8

注, 你們能夠看到,如今又能夠從新訪問,說明nginx的健康狀態查檢配置成功。但你們想一下,若是不幸的是全部服務器都不能提供服務了怎麼辦,用戶打開頁面 就會出現出錯頁面,那麼會帶來用戶體驗的下降,因此咱們能不能像配置LVS是配置sorry_server呢,答案是能夠的,但這裏不是配置 sorry_server而是配置backup。

12.配置backup服務器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@nginx ~] # vim /etc/nginx/nginx.conf
server {
                 listen 8080;
                 server_name localhost;
                 root /data/www/errorpage ;
                 index index.html;
         }
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;
         server 127.0.0.1:8080 backup;
     }
[root@nginx ~] # mkdir -pv /data/www/errorpage
[root@nginx errorpage] # cat index.html
<h1>Sorry......< /h1 >

13.從新加載配置文件

1
2
3
4
[root@nginx errorpage] # 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:                                           [肯定]

14.關閉Web服務器並進行測試

1
2
3
4
[root@web1 ~] # service httpd stop
中止 httpd:                                               [肯定]
[root@web2 ~] # service httpd stop
中止 httpd:                                               [肯定]

t9

注,你們能夠看到,當全部服務器都不能工做時,就會啓動備份服務器。好了,backup服務器就配置到這裏,下面咱們來配置ip_hash負載均衡。

15.配置ip_hash負載均衡

  • ip_hash,每一個請求按訪問IP的hash結果分配,這樣來自同一個IP的訪客固定訪問一個後端服務器,有效解決了動態網頁存在的session共享問題。(通常電子商務網站用的比較多)

1
2
3
4
5
6
7
[root@nginx ~] # vim /etc/nginx/nginx.conf
upstream webservers {
         ip_hash;
         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;
         #server 127.0.0.1:8080 backup;
     }

注,當負載調度算法爲ip_hash時,後端服務器在負載均衡調度中的狀態不能有backup。(有人可能會問,爲何呢?你們想啊,若是負載均衡把你分配到backup服務器上,你能訪問到頁面嗎?不能,因此了不能配置backup服務器)

16.從新加載一下服務器

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:                                           [肯定]

17.測試一下

t10

注,你們能夠看到,你不斷的刷新頁面一直會顯示的民Web2,說明ip_hash負載均衡配置成功。下面咱們來統計一下Web2的訪問鏈接數。

18.統計Web2的訪問鏈接數

1
2
[root@web2 ~] # netstat -an | grep :80 | wc -l
304

注,你不斷的刷新,鏈接數會愈來愈多。好了,nginx的負載均衡就所有演示到這裏下面咱們來講一說,頁面緩存。

6、Nginx之頁面緩存

1.指令說明

proxy_cache_path

語法:proxy_cache_path path [levels=number] keys_zone=zone_name:zone_size [inactive=time] [max_size=size];  
默認值:None  
使用字段:http  
指令指定緩存的路徑和一些其餘參數,緩存的數據存儲在文件中,而且使用代理url的哈希值做爲關鍵字與文件名。levels參數指定緩存的子目錄數,例如:

1
proxy_cache_path  /data/nginx/cache  levels=1:2   keys_zone=one:10m;

文件名相似於:

1
/data/nginx/cache/c/29/b7f54b2df7773722d382f4809d65029c

levels指定目錄結構,可使用任意的1位或2位數字做爲目錄結構,如 X, X:X,或X:X:X 例如: 「2」, 「2:2」, 「1:1:2「,可是最多隻能是三級目錄。  
全部活動的key和元數據存儲在共享的內存池中,這個區域用keys_zone參數指定。one指的是共享池的名稱,10m指的是共享池的大小。  
注意每個定義的內存池必須是不重複的路徑,例如:

1
2
3
proxy_cache_path  /data/nginx/cache/one    levels=1      keys_zone=one:10m;
proxy_cache_path  /data/nginx/cache/two    levels=2:2    keys_zone=two:100m;
proxy_cache_path  /data/nginx/cache/three  levels=1:1:2  keys_zone=three:1000m;

如 果在inactive參數指定的時間內緩存的數據沒有被請求則被刪除,默認inactive爲10分鐘。一個名爲cache manager的進程控制磁盤的緩存大小,它被用來刪除不活動的緩存和控制緩存大小,這些都在max_size參數中定義,當目前緩存的值超出 max_size指定的值以後,超過其大小後最少使用數據(LRU替換算法)將被刪除。內存池的大小按照緩存頁面數的比例進行設置,一個頁面(文件)的元 數據大小按照操做系統來定,如FreeBSD/i386下爲64字節,FreeBSD/amd64下爲128字節。

proxy_cache

語法:proxy_cache zone_name;  
默認值:None  
使用字段:http, server, location  
設置一個緩存區域的名稱,一個相同的區域能夠在不一樣的地方使用。  
在 0.7.48後,緩存遵循後端的」Expires」, 「Cache-Control: no-cache」, 「Cache-Control: max-age=XXX」頭部字段,0.7.66版本之後,」Cache-Control:「private」和」no-store」頭一樣被遵循。 nginx在緩存過程當中不會處理」Vary」頭,爲了確保一些私有數據不被全部的用戶看到,後端必須設置 「no-cache」或者」max-age=0」頭,或者proxy_cache_key包含用戶指定的數據如$cookie_xxx,使用cookie 的值做爲proxy_cache_key的一部分能夠防止緩存私有數據,因此能夠在不一樣的location中分別指定proxy_cache_key的值 以便分開私有數據和公有數據。  
緩存指令依賴代理緩衝區(buffers),若是proxy_buffers設置爲off,緩存不會生效。

proxy_cache_valid

語法:proxy_cache_valid reply_code [reply_code …] time;  
默認值:None  
使用字段:http, server, location  
爲不一樣的應答設置不一樣的緩存時間,例如:

1
2
proxy_cache_valid  200 302  10m;
proxy_cache_valid  404      1m;

爲應答代碼爲200和302的設置緩存時間爲10分鐘,404代碼緩存1分鐘。  
若是隻定義時間:

1
proxy_cache_valid 5m;

那麼只對代碼爲200, 301和302的應答進行緩存。  
一樣可使用any參數任何應答。

1
2
3
proxy_cache_valid  200 302 10m;
proxy_cache_valid  301 1h;
proxy_cache_valid  any 1m;

2.定義一個簡單nginx緩存服務器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@nginx ~] # vim /etc/nginx/nginx.conf
proxy_cache_path /data/nginx/cache/webserver levels=1:2 keys_zone=webserver:20m max_size=1g;
    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;
                proxy_cache webserver;
                proxy_cache_valid 200 10m;
        }
}

3.新建緩存目錄

1
[root@nginx ~] # mkdir -pv /data/nginx/cache/webserver

4.從新加載一下配置文件

1
2
3
4
[root@nginx webserver] # 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:                                           [肯定]

5.下面咱們來測試一下(谷歌瀏覽器)

t11

注,你們用谷歌瀏覽器測試的時候,能夠按F12調用開發工具,選擇Network選項,咱們能夠看到,Response Headers,在這裏咱們能夠看到,咱們請求的是不是緩存,但如今還看不到,下面咱們來配置一下,再來測試。

6. 緩存變量說明

$server_addr

服務器地址,在完成一次系統調用後能夠肯定這個值,若是要繞開系統調用,則必須在listen中指定地址而且使用bind參數。

$upstream_cache_status

0.8.3版本中其值可能爲:

  • MISS 未命中

  • EXPIRED - expired。請求被傳送到後端。

  • UPDATING - expired。因爲proxy/fastcgi_cache_use_stale正在更新,將使用舊的應答。

  • STALE - expired。因爲proxy/fastcgi_cache_use_stale,後端將獲得過時的應答。

  • HIT 命中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@nginx ~] # vim /etc/nginx/nginx.conf
proxy_cache_path /data/nginx/cache/webserver levels=1:2 keys_zone=webserver:20m max_size=1g;
     server {
         listen       80;
         server_name  localhost;
         #charset koi8-r;
         #access_log  logs/host.access.log  main;
        #增長兩頭部
         add_header X-Via $server_addr;
         add_header X-Cache $upstream_cache_status;
         location / {
                 proxy_pass      http: //webservers ;
                 proxy_set_header  X-Real-IP  $remote_addr;
                 proxy_cache webserver;
                 proxy_cache_valid 200 10m;
         }
}

7.從新加載一下配置文件

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:                                           [肯定]

8.測試一下

t12

注,從圖中咱們能夠看到,咱們訪問的服務器是192.168.18.208,緩存命中。你們能夠看到是否是很直觀啊。下面咱們看一下緩存目錄。

9.查看一下緩存目錄

1
2
3
[root@nginx ~] # cd /data/nginx/cache/webserver/f/63/
[root@nginx 63] # ls
681ad4c77694b65d61c9985553a2763f

注,緩存目錄裏確實有緩存文件。好了,nginx緩存配置就到這邊了,更多配置請根據須要看配置文檔。下面咱們來講一下,URL重寫。

7、Nginx之URL重寫

1.URL重寫模塊(Rewrite)

摘要

這 個模塊容許使用正則表達式重寫URI(需PCRE庫),而且能夠根據相關變量重定向和選擇不一樣的配置。若是這個指令在server字段中指定,那麼將在被 請求的location肯定以前執行,若是在指令執行後所選擇的location中有其餘的重寫規則,那麼它們也被執行。若是在location中執行這 個指令產生了新的URI,那麼location又一次肯定了新的URI。這樣的循環能夠最多執行10次,超過之後nginx將返回500錯誤。

指令

break

語法:break  
默認值:none  
使用字段:server, location, if  
完成當前設置的規則,中止執行其餘的重寫指令。  
示例:

1
2
3
4
if ($slow) {
   limit_rate  10k;
   break ;
}
if

語法:if (condition) { … }  
默認值:none  
使用字段:server, location  
注意:在使用if指令以前請查看if is evil page而且儘可能考慮用try_files代替。  
判斷一個條件,若是條件成立,則後面的大括號內的語句將執行,相關配置從上級繼承。  
能夠在判斷語句中指定下列值:

  • 一個變量的名稱;不成立的值爲:空字符傳」「或者一些用「0」開始的字符串。

  • 一個使用=或者!=運算符的比較語句。

  • 使用符號~*和~模式匹配的正則表達式:

  • ~爲區分大小寫的匹配。

  • ~*不區分大小寫的匹配(firefox匹配FireFox)。

  • !~和!~*意爲「不匹配的」。

  • 使用-f和!-f檢查一個文件是否存在。

  • 使用-d和!-d檢查一個目錄是否存在。

  • 使用-e和!-e檢查一個文件,目錄或者軟連接是否存在。

  • 使用-x和!-x檢查一個文件是否爲可執行文件。

正則表達式的一部分能夠用圓括號,方便以後按照順序用$1-$9來引用。  
示例配置:

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
if ($http_user_agent ~ MSIE) {
   rewrite  ^(.*)$  /msie/ $1  break ;
}
                                                                                                                                                        
if ($http_cookie ~* "id=([^;] +)(?:;|$)" ) {
   set  $ id  $1;
}
                                                                                                                                                        
if ($request_method = POST ) {
   return 405;
}
                                                                                                                                                        
if (!-f $request_filename) {
   break ;
   proxy_pass  http: //127 .0.0.1;
}
                                                                                                                                                        
if ($slow) {
   limit_rate  10k;
}
                                                                                                                                                        
if ($invalid_referer) {
   return   403;
}
                                                                                                                                                        
if ($args ~ post=140){
   rewrite ^ http: //example .com/ permanent;
}

內置變量$invalid_referer用指令valid_referers指定。

return

語法:return code  
默認值:none  
使用字段:server, location, if  
這個指令結束執行配置語句併爲客戶端返回狀態代碼,可使用下列的值:204,400,402-406,408,410, 411, 413, 416與500-504。此外,非標準代碼444將關閉鏈接而且不發送任何的頭部。

rewrite

語法:rewrite regex replacement flag  
默認值:none  
使用字段:server, location, if  
按照相關的正則表達式與字符串修改URI,指令按照在配置文件中出現的順序執行。  
能夠在重寫指令後面添加標記。  
若是替換的字符串以http://開頭,請求將被重定向,而且再也不執行多餘的rewrite指令。  
尾部的標記(flag)能夠是如下的值:

  • last - 完成重寫指令,以後搜索相應的URI或location。

  • break - 完成重寫指令。

  • redirect - 返回302臨時重定向,若是替換字段用http://開頭則被使用。

  • permanent - 返回301永久重定向。

注 意若是一個重定向是相對的(沒有主機名部分),nginx將在重定向的過程當中使用匹配server_name指令的「Host」頭或者 server_name指令指定的第一個名稱,若是頭不匹配或不存在,若是沒有設置server_name,將使用本地主機名,若是你老是想讓nginx 使用「Host」頭,能夠在server_name使用「*」通配符(查看http核心模塊中的server_name)。例如:

1
2
3
rewrite  ^( /download/ .*) /media/ (.*)\..*$  $1 /mp3/ $2.mp3  last;
rewrite  ^( /download/ .*) /audio/ (.*)\..*$  $1 /mp3/ $2.ra   last;
return   403;

可是若是咱們將其放入一個名爲/download/的location中,則須要將last標記改成break,不然nginx將執行10次循環並返回500錯誤。

1
2
3
4
5
location /download/ {
   rewrite  ^( /download/ .*) /media/ (.*)\..*$  $1 /mp3/ $2.mp3  break ;
   rewrite  ^( /download/ .*) /audio/ (.*)\..*$  $1 /mp3/ $2.ra   break ;
   return   403;
}

若是替換字段中包含參數,那麼其他的請求參數將附加到後面,爲了防止附加,能夠在最後一個字符後面跟一個問號:

1
rewrite  ^ /users/ (.*)$  /show ?user=$1?  last;

注意:大括號({和}),能夠同時用在正則表達式和配置塊中,爲了防止衝突,正則表達式使用大括號須要用雙引號(或者單引號)。例如要重寫如下的URL:

1
/photos/123456

爲:

1
/path/to/photos/12/1234/123456 .png

則使用如下正則表達式(注意引號):

1
rewrite  "/photos/([0-9] {2})([0-9] {2})([0-9] {2})" /path/to/photos/ $1/$1$2/$1$2$3.png;

若是指定一個「?」在重寫的結尾,Nginx將丟棄請求中的參數,即變量$args,當使用$request_uri$uri&$args時能夠在rewrite結尾使用「?」以免nginx處理兩次參數串。  
在rewrite中使用$request_uri將www.example.com重寫到example.com:

1
2
3
4
server {
    server_name www.example.com;
    rewrite ^ http: //example .com$request_uri? permanent;
}

一樣,重寫只對路徑進行操做,而不是參數,若是要重寫一個帶參數的URL,可使用如下代替:

1
2
3
if ($args ^~ post=100){
   rewrite ^ http: //example .com /new-address .html? permanent;
}

注意$args變量不會被編譯,與location過程當中的URI不一樣(參考http核心模塊中的location)。

rewrite_log

語法:rewrite_log on | off  
默認值:rewrite_log off  
使用字段:server, location, if  
變量:無  
啓用時將在error log中記錄notice 標記的重寫日誌。

set

語法:set variable value  
默認值:none  
使用字段:server, location, if  
指令設置一個變量併爲其賦值,其值能夠是文本,變量和它們的組合。  
你可使用set定義一個新的變量,可是不能使用set設置$http_xxx頭部變量的值。

uninitialized_variable_warn

語法:uninitialized_variable_warn on|off  
默認值:uninitialized_variable_warn on  
使用字段:http, server, location, if  
開啓或關閉在未初始化變量中記錄警告日誌。  
事實上,rewrite指令在配置文件加載時已經編譯到內部代碼中,在解釋器產生請求時使用。  
這個解釋器是一個簡單的堆棧虛擬機,以下列指令:

1
2
3
4
5
6
7
8
location /download/ {
   if ($forbidden) {
     return   403;
   }
   if ($slow) {
     limit_rate  10k;
   }
   rewrite  ^/(download/.*) /media/ (.*)\..*$  /$1 /mp3/ $2.mp3  break ;

將被編譯成如下順序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
variable $forbidden
checking to zero
recovery 403
completion of entire code
variable $slow
checking to zero
checkings of regular excodession
copying "/"
copying $1
copying "/mp3/"
copying $2
copying ".mp3"
completion of regular excodession
completion of entire sequence

注意並無關於limit_rate的代碼,由於它沒有說起ngx_http_rewrite_module模塊,「if」塊能夠相似」location」指令在配置文件的相同部分同時存在。  
若是$slow爲真,對應的if塊將生效,在這個配置中limit_rate的值爲10k。  
指令:

1
rewrite  ^/(download/.*) /media/ (.*)\..*$  /$1 /mp3/ $2.mp3  break ;

若是咱們將第一個斜槓括入圓括號,則能夠減小執行順序:

1
rewrite  ^( /download/ .*) /media/ (.*)\..*$  $1 /mp3/ $2.mp3  break ;

以後的順序相似以下:

1
2
3
4
5
6
7
checking regular excodession
copying $1
copying "/mp3/"
copying $2
copying ".mp3"
completion of regular excodession
completion of entire code
2.簡單案例
注,因爲配置文件內容較多,爲了讓你們看着方便,咱們備份一下配置文件,打開一個新的配置文件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@nginx ~] # cd /etc/nginx/
[root@nginx nginx] # mv nginx.conf nginx.conf.proxy
[root@nginx nginx] # cp nginx.conf.bak nginx.conf
[root@nginx nginx] # vim /etc/nginx/nginx.conf
server {
       listen       80;
       server_name  localhost;
       #charset koi8-r;
       #access_log  logs/host.access.log  main;
       location / {
           root   html;
           index  index.html index.htm;
           rewrite ^ /bbs/ (.*)$ http: //192 .168.18.201 /forum/ $1;
       }
}
準備forum目錄與測試文件
1
2
3
4
5
6
7
[root@web1 ~] # cd /var/www/html/
[root@web1 html] # ls
index.html
[root@web1 html] # mkdir forum
[root@web1 html] # cd forum/
[root@web1 forum] # vim index.html
<h1>forum page!< /h1 >

測試一下

t13

好了,下面咱們來測試一下rewrite重寫。

3.從新加載一下配置文件
1
2
3
4
[root@nginx 63] # 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:                                           [肯定]

4.測試一下

t14

注, 你們能夠從圖中看出,status code 302指的是臨時重定向,那就說明咱們rewrite重寫配置成功。你們知道302是臨時重定向而301是永久重定向,那麼怎麼實現永久重定向呢。通常服 務器與服務器之間是臨時重定向,服務器內部是永久重定向。下面咱們來演示一下永久重定向。

5.配置永久重定向

1
2
3
4
5
6
7
8
9
10
11
12
[root@nginx nginx] # vim /etc/nginx/nginx.conf
server {
         listen       80;
         server_name  localhost;
         #charset koi8-r;
         #access_log  logs/host.access.log  main;
         location / {
             root   html;
             index  index.html index.htm;
             rewrite ^ /bbs/ (.*)$ /forum/ $1;
         }
}
準備forum目錄與測試文件
1
2
3
4
5
6
7
[root@nginx ~] # cd /usr/html/
[root@nginx html] # ls
50x.html  index.html
[root@nginx html] # mkdir forum
[root@nginx html] # cd forum/
[root@nginx forum] # vim index.html
<h1>192.168.18.208 forum page< /h1 >

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.測試一下

t16

注,你們從圖中能夠看到,咱們訪問bbs/是直接幫咱們跳轉到forum/下,這種本機的跳轉就是永久重定向也叫隱式重定向。好了,rewrite重定向咱們就說到這裏了,想要查詢更多關於重定向的指令請參考官方文檔。最後,咱們來講一下讀寫分離。

8、Nginx之讀寫分離

1.實驗拓撲

nginx3

       需求分析,前端一臺nginx作負載均衡反向代理,後面兩臺httpd服務器。整個架構是提供BBS(論壇)服務,有一需求得實現讀寫分離,就是上傳附 件的功能,咱們上傳的附件只能上傳到Web1,而後在Web1上利用rsync+inotify實現附件同步,你們都知道rsync+inotify只能 是主向從同步,不能雙向同步。因此Web1可進行寫操做,而Web2只能進行讀操做,這就帶來讀寫分離的需求,下面咱們就來講一下,讀寫分離怎麼實現。

2.WebDAV功能說明

       WebDAV (Web-based Distributed Authoring and Versioning) 一種基於 HTTP 1.1協議的通訊協議。它擴展了HTTP 1.1,在GET、POST、HEAD等幾個HTTP標準方法之外添加了一些新的方法,使應用程序可直接對Web Server直接讀寫,並支持寫文件鎖定(Locking)及解鎖(Unlock),還能夠支持文件的版本控制。這樣咱們就能配置讀寫分離功能了,下面我 們來具體配置一下。

3.修改配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@nginx nginx] # vim /etc/nginx/nginx.conf
server {
         listen       80;
         server_name  localhost;
         #charset koi8-r;
         #access_log  logs/host.access.log  main;
         location / {
                 proxy_pass http: //192 .168.18.202;
                 if ($request_method = "PUT" ){
                         proxy_pass http: //192 .168.18.201;
                 }
         }
}

4.從新加載一下配置文件

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:                                           [肯定]

5.配置httpd的WebDAV功能

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

t17

注,在<Directory "/var/www/html">下啓用就行。

6.從新啓動一下httpd

1
2
3
[root@web1 ~] # service httpd restart
中止 httpd:                                               [肯定]
正在啓動 httpd:                                           [肯定]

7.測試一下

1
2
3
4
[root@nginx ~] # curl http://192.168.18.201
<h1>web1. test .com< /h1 >
[root@nginx ~] # curl http://192.168.18.202
<h1>web2. test .com< /h1 >

注,web1與web2訪問都沒問題。

1
2
3
4
5
6
7
8
9
10
[root@nginx ~] # curl -T /etc/issue  http://192.168.18.202
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN" >
<html>< head >
<title>405 Method Not Allowed< /title >
< /head ><body>
<h1>Method Not Allowed< /h1 >
The requested method PUT is not allowed for the URL /issue .
<hr>
<address>Apache /2 .2.15 (CentOS) Server at 192.168.18.202 Port 80< /address >
< /body >< /html >

注,咱們上傳文件到,web2上時,由於web2只人讀功能,因此沒有開戶WebDAV功能,因此顯示是405 Method Not Allowed。  

1
2
3
4
5
6
7
8
9
10
11
[root@nginx ~] # curl -T /etc/issue  http://192.168.18.201
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN" >
<html>< head >
<title>403 Forbidden< /title >
< /head ><body>
<h1>Forbidden< /h1 >
You don't have permission to access /issue
on this server.
<hr>
<address>Apache /2 .2.15 (CentOS) Server at 192.168.18.201 Port 80< /address >
< /body >< /html >

注,咱們在Web1開啓了WebDAV功能,但咱們目錄是root目錄是不容許apache用戶上傳的,因此顯示的是403 Forbidden。下面咱們給apache受權,容許上傳。

1
[root@web1 ~] # setfacl -m u:apache:rwx /var/www/html/

下面咱們再來測試一下,

1
2
3
4
5
6
7
8
9
10
[root@nginx ~] # curl -T /etc/issue  http://192.168.18.201
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN" >
<html>< head >
<title>201 Created< /title >
< /head ><body>
<h1>Created< /h1 >
Resource /issue has been created.
<hr />
<address>Apache /2 .2.15 (CentOS) Server at 192.168.18.201 Port 80< /address >
< /body >< /html >

注,你們能夠看到咱們成功的上傳了文件,說明nginx讀寫分離功能配置完成。最後,咱們來查看一下上傳的文件。

1
2
3
4
5
6
[root@web1 ~] # cd /var/www/html/
[root@web1 html] # ll
總用量 12
drwxr-xr-x 2 root   root   4096 9月   4 13:16 forum
-rw-r--r-- 1 root   root     23 9月   3 23:37 index.html
-rw-r--r-- 1 apache apache   47 9月   4 14:06 issue

好了,到這裏nginx的反向代理、負載均衡、頁面緩存、URL重寫及讀寫分離就所有講解完成。但願你們有所收穫,^_^……Nginx 反向代理、負載均衡、頁面緩存、URL重寫及讀寫分離詳解

相關文章
相關標籤/搜索