Nginx實現反向代理負載均衡


來源:http://blog.chinaunix.net/uid-29792372-id-5760630.html

網絡模型中,nginx屬於第7層,根據域名或目錄配置負載均衡(代理),十分靈活;而lvs只能針對IP

環境:

DIR :   172.16.115.100(Nginx代理)

RS1:    172.16.115.157(Web服務器)

RS2:    172.16.115.202(Web服務器)


1. dir、rs1、rs2安裝nginx(1台代理+2台Web服務器)

    命令 yum install -y nginx


2. 編輯dir上nginx的配置文件/etc/nginx/nginx.conf,開啟子配置文件include /etc/nginx/conf.d/*.conf,並新建配置文件/etc/nginx/conf.d/lb.conf

    說明:用到uptream模塊,定義負載均衡中服務器

    內容:


 upstream hzp {

        server 172.16.115.157:80;

        server 172.16.115.202:80;

        }

   server {

       listen 80;

       server_name www.huangzhenping.cn;

        location / {

        proxy_pass http://hzp/;

        proxy_set_header Host $host;

           }

        }


   注:需禁用掉/etc/nginx/conf.d/default.conf文件,如改名為default.conf.bak


3. 修改rs1和rs2服務器web首頁,並啟動三台服務器上的Nginx服務

    命令 /etc/init.d/nginx start

    rs1:echo "hello,rs1" > /usr/share/nginx/html/index.html

    rs2:echo "hello,rs2" > /usr/share/nginx/html/index.html


4. 客戶機上用curl測試:curl -xlocalhost:80 www.huangzhenping.cn

    結果: 權重1:1交替訪問

wKioL1i1Nw2AcqJCAABAGg7vT70993.png

5. dir上,修改配置文件/usr/local/nginx/conf/vhosts/lb.conf,增加權重,重啟測試

    內容:


upstream hzp {

        server 172.16.115.157:80 weight=3;

        server 172.16.115.202:80 weight=1;

        }

   server {

       listen 80;

       server_name www.huangzhenping.cn;

        location / {

        proxy_pass http://hzp/;

        proxy_set_header Host $host;

           }

        }

結果:3:1關系,交替訪問

     wKioL1i1N2Oxb9yQAABIjGZnaG8038.png


6. 停止rs1上的nginx服務,再次測試

    結果:跳過rs1服務器,只訪問rs2的Web;恢復rs1時,交替訪問

 wKioL1i1N3aw3XKmAABKN3MDRPs914.png

 wKiom1i1N3fzLFZ-AAAueT59hS4242.png

nginx負載均衡簡單配置


准備三台虛擬機來做這個實驗:


172.16.100.6        web服務器

172.16.100.7        web服務器

172.16.100.106    負載均衡服務器


首先三台電腦裝好nginx軟件:

向web服務器中放入測試文件:


   

   

Welcome to nginx!    

   

   


Welcome to nginx! 172.16.100.6

   


   



配置負載均衡服務器:


vi /usr/local/nginx/conf/nginx.conf


user nginx nginx;worker_processes  1;


events {

    worker_connections  1024;

}


http {

    include       mime.types;

    default_type  application/octet-stream;    

    sendfile       on;

    keepalive_timeout  65;

    upstream webservs {

        server 172.16.100.6 weight=1;

        server 172.16.100.7 weight=1;

    }


    server {

        listen     8083;

        server_name  localhost;

        index index.html index.htm index.php; 

         location / {

             proxy_pass webservs;

           proxy_set_header X-Real-IP $remote_addr;

        }


        error_page   500 502 503 504  /50x.html;

        location = /50x.html {

            root   html;

        }

    }

}


拓展:

要在server之外定義upstream ,upstream可以定義多個名稱,但每一個upstream都要有自己獨立的名稱

upstream里有很多的子指定,其中server用來定義每一個后端服務器;


每一個后端還可以傳遞很多參數,weight權重,沒有權重為0,不做負載均衡的,權重一樣就輪調,權重不一樣實現加權輪調,還可以實現端口映射;定義server時只能定義名稱或是IP地址,不能使用協議http。



upstream backend {

    server backend1.example.com weight=5;

    server backend2.example.com:8080;

    server unik:/tmp/backend3;

}

server{

    location / {

        proxy_pass http://backend;    //反向代理不是某些主機,而是upstream定義的名稱,,由upstream來實現負載均衡功能

    }

}





ngin的負載均衡得用到upstream模塊,它用來定義一個后端服務器組,即把所有后端的服務器整合在一起,然后通過proxy代理到這個服務器組。就能實現簡單的http負載均衡了,


upstream默認的調度方式是wrr(具體內容可參考lvs中的介紹),所以我們只用指定服務器的ip,如果端口不是默認80端口也可以單獨指定,還有一些調度用到的參數,比如權重。



http{

    ...

    upstream backserver {                   #backserver是一個自定義的名字,后面會調用

            server 172.16.53.101;           #第一個后端server

            server 172.16.53.102 ;          #第二個后端server

        }

    ...

    server {                                

        listen 80;

        server_name xiaofengfeng.cn;

        location / {

                proxy_pass      #代理到服務器組,此處只支持http/https 

                index index.html;

        }

}

上面就是一個最簡單的基於nginx的服務均衡配置了。upstream 的server后面還可以加許多參數,比如設置不同的權值weight=number,權值越大調用的次數越多。backup參數可以設置backup server,比如我們可以設置本機為backup server,當后端服務器都不能訪問的時候,我們本機可以提供一個sorry 頁面。


 http{

     ...

    upstream backserver {

            server 172.16.53.101;

            server 172.16.53.102 ;

            server 127.0.0.1 backup; 

               #指定本機回環地址為備用server,此處我們提供一個sorry server

        }

    server {

            listen 192.168.157.128:80;   #代理服務只監聽前端服務的ip和端口

            server_name xiaofengfeng.cn;

            location / {

                    proxy_pass  http://backserver;

                    index index.html;

            }

    }

    server {

            listen 127.0.0.1:80;          #回環地址用來做sorry server

            server_name xiaofengfeng2.cn;

            location / {

                    root /var/nginx;

                    index index.html;

            }

    }

}

    注:因為我們改變了監聽的ip所以得重啟nginx服務,而不是用nginx -s reload。

    除了server配置選項還有其他一些常用的,比如我們可以改變其調用算法為wlc,即least_conn,就會根據后端服務器的連接數來調用。如果我們的一些用戶信息,比如說session,cookie等保存在后端服務器本地,為了放置用戶信息丟失,我們可以讓一個用戶的請求都發送到同一個后端服務器。ip_hash就可以實現這樣的功能。來自同一個源IP地址的請求始終發往同一個upstream server。除了根據源地址hash,我們還可以指定特定的參數來作為hash的條件,比如,如果我們用uri作為hash條件,那么同一個uri的請求會發往同一台后端服務器。此時我們就要用到hash選項,比如:



hash $request_uri consistent

$request_uri是內置提供的變量,就是請求的uri咯,consistent是一致性哈希算法,這個倒是可以說道說道。我們知道哈希就是無論輸入什么值,都會得到一個固定長度的散列值,我們對不同的uri求散列值,如果后端服務器有6台服務器,然后給他們進行編號0-6,然后用求的散列值對6做取余運算,就一定會得到0-6中的一個值,然后把這個分配給對應編號的服務器。不過,這個算法有個問題,如果某個服務器掛掉,我們就得重新以5來做取余運算,然后重新把所有過程從來一遍。所以就出現了上面的一致性哈希算法,我們現在先不關注后端有幾台服務器,我們把0到2的32次方減一這個多個數字分布在一個圓環上,就上鍾表上的0-12一樣,0的地方就是12.然后我們對后端每個服務器的ip地址做哈希計算,得到的值在和2的32次方做取余運算,那么后端的這些服務器一定會分布在這個圓環上的某個點處,然后我們在對hash選項指定的內容,此處是uri做hash計算,得到的值在和2的32次方取余,所以這些uri也會分布在這個圓環上。然后我們規定,在這個圓環上分布的服務器,負責響應它到它下一個服務器的區間上分布的請求。此時當后端的某台服務器掛掉時,只會影響這台服務器后面的URI請求,而不會影響其他服務器,只用把屬於這台服務器的請求,給它上一台就好,我們畫個圖說明下。


我們用方塊表示后端服務器經過哈希計算的分布情況,用紅色的線表示不同uri請求的分布情況,服務器1只用負責1到2之間的uri請求,以此類推,5只用負責5到1之間的uri請求,如右圖所示,假如2號服務器掛掉了,我們就把所有屬於2號服務器的請求分配給1號服務器~好啦~這就是一致性哈希算法~~~很重要喲,許多地方都有用到。

    除了支持web服務的負載均衡,nginx還支持其他服務的負載均衡,此時我們就得用到另外的模塊stream和stream_proxy_module。不過這兩個模塊必須得是1.9.13以上的版本~並且默認stream並沒有加載。得在編譯時加入--with-stream選項,不過如果我們用的是預編譯的rpm包安裝的話,默認是有這個的~以下是/etc/nginx/nginx.conf


user  nginx;

worker_processes  1;


error_log  /var/log/nginx/error.log warn;

pid        /var/run/nginx.pid;



events {

    worker_connections  1024;

}

stream {

        upstream sshsrvs {

                server 192.168.10.130:22;

                server 192.168.10.131:22;

        }


        server {

                listen 172.16.100.6:22202;

                proxy_pass sshsrvs;

                proxy_timeout 60s;

                proxy_connect_timeout 10s;

        }


}

使用Nginx+Keepalived組建高可用負載平衡Web server集群

一,首先說明一下網絡拓撲結構:

1,Nginx 反向代理Server(HA):

     ①Nginx master:192.168.1.157

     ②Nginx backup:192.168.1.158  

      虛擬IP統一為:192.168.1.110    

2,web服務器:

     192.168.1.160 ,192.168.1.161,192.168.1.162      即web服務器,已配置好 Tomcat(Jboss等皆可)和Java程序

3,MySQL 數據庫Server

     mysql主從服務器


二,Nginx安裝配置

1,安裝

建議先用yum install yum-fastestmirror更新下源


下載並安裝nginx1.0.9,下載文件均放到/usr/local/src目錄下

cd /usr/local/src


①update yum

 yum -y update


②利用CentOS Linux系統自帶的yum命令安裝、升級所需的程序庫

安裝依賴包

#yum install gcc pcre pcre-devel zlib zlib-devel openssl openssl-devel


下載nginx

#cd /usr/local/src

#wget http://www.nginx.org/download/nginx-1.0.9.tar.gz

#tar zxvf nginx-1.0.9.tar.gz

#cd nginx-1.0.9


配置安裝:

#./configure --prefix=/usr --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.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_gzip_static_module --http-log-path=/var/log/nginx/access.log --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/

#make

#make install


建立用戶:

/usr/sbin/groupadd nginx

/usr/sbin/useradd -g nginx -M nginx

mkdir -p /var/tmp/nginx/client

啟動nginx

#/usr/sbin/nginx



 ps:如果中途提示缺少庫,直接yum install xxx即可。

 即:conf-path=/etc/nginx/nginx.conf,用戶名為nginx,所屬的組為nginx


       2,配置

Nginx負載均衡設置:


①修改配置文件:

vi /etc/nginx/nginx.conf

步驟1,添加負載均衡的http upstream模塊

upstream  esbwebserver  {

  server   192.168.1.160:8888;

  server   192.168.1.161:8888;

}


步驟2,server指令

server

{

listen  80;

server_name  localhost;#注意此處為localhost


location / {

       proxy_pass        http://esbwebserver;# 添加的tomcat集群名稱

       ......

}


②,重啟Nginx,加載修改過的配置文件:

步驟1, 停止nginx引擎

killall -9 nginx

步驟2,啟動nginx

/usr/sbin/nginx


到此為止,我們的負載均衡就實現了,下面實現Nginx的高可用,即雙機熱備。


三,Keepalived 安裝配置

1,下載並安裝keepalived-1.1.15.tar.gz,下載文件均放到/usr/local/src目錄下

cd /usr/local/src

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


①解壓縮

tar zxvf keepalived-1.1.15.tar.gz


②安裝

cd keepalived-1.1.15

./configure --prefix=/usr/local/keepalived

make && make install

③安裝成功后做成服務模式,方便啟動和關閉

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

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

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



④ 分別設置主和備Nginx上的 安裝Keepalived配置文件。


  配置文件位置:

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


 步驟一,先配置主Nginx server上的keepalived.conf文件,如下所示:

 ! Configuration File for keepalived


  global_defs {

  notification_email {

    644856452@qq.com

  }

  notification_email_from 644856452@qq.com

  smtp_server 127.0.0.1

  smtp_connect_timeout 30

  router_id LVS_DEVEL

}



vrrp_script check_run {

   script "/root/bin/nginx_check.sh"

   interval 5

}

vrrp_sync_group VG1 {

    group {

       VI_1

    }

}

vrrp_instance VI_1 {

   state MASTER

   interface eth0

   virtual_router_id 51

   mcast_src_ip 192.168.1.157

   priority 100

   advert_int 1

   authentication {

       auth_type PASS

       auth_pass 1111

   }

 track_script {

        check_run

    }


   virtual_ipaddress {

       192.168.1.110

   }

}


步驟二,配置backup 服務器的keepalived.conf文件,如下所示:

! Configuration File for keepalived


global_defs {

  notification_email {

    644856452@qq.com     

  }

  notification_email_from Alexandre.Cassen@firewall.loc

  smtp_server 127.0.0.1

  smtp_connect_timeout 30

  router_id LVS_DEVEL

}

vrrp_script check_run {

   script "/root/bin/nginx_check.sh"

   interval 5

}

vrrp_sync_group VG1 {

    group {

      VI_1 

    }

}



vrrp_instance VI_1 {

   state BACKUP

   interface eth0

   virtual_router_id 51

   priority 99

   advert_int 1

   authentication {

       auth_type PASS

       auth_pass 1111

   }

track_script {

        check_run

    }

   virtual_ipaddress {

       192.168.1.110

   }

}


參考下例配置:

-----------------------------------------------------帶注釋的示例----------------------------------------------------

在主服務器編寫配置文件

vrrp_script check_run{

                script "/opt/nginx_pid.sh"         ###監控腳本

                interval 2                             ###監控時間

                weight 2                                ###如果檢測返回值不為真weight 2 表示減2,權重值降低,backup server權重值>現Master的,切換

}

vrrp_instance VI_1 {

        state MASTER                           ### 設置為 主

        interface eth0                            ### 監控網卡    

        virtual_router_id 51                  ### 這個兩台服務器必須一樣

        priority 101                                 ### 權重值 MASTRE 一定要高於 BAUCKUP

        authentication {

                     auth_type PASS             ### 加密

                     auth_pass 1111          ###加密的密碼,兩台服務器一定要一樣,不然會出錯

}


       track_script {

                check_run     ### 執行監控的服務

        }


        virtual_ipaddress {

             192.168.1.110                          ###    VIP 地址

        }

}

6.在backup server  服務器 keepalived 配置

vrrp_script check_run{

                script "/opt/nginx_pid.sh"

                interval  2

                weight   2

}



vrrp_instance VI_1 {

       state BACKUP                                ### 設置為 輔機

        interface eth0

        virtual_router_id 51                      ### 與 MASTRE 設置 值一樣

        priority 100                                     ### 比 MASTRE權重值 低


        authentication {

                     auth_type PASS

                     auth_pass eric                    ### 密碼 與 MASTRE 一樣

        }


        track_script {

                check_run

        }

virtual_ipaddress {

                 192.168.1.110

        }

}

----------------------------------------------over------------------------------------------------------------------- 


說明:  

1,綁定虛擬IP:

  ifconfig eth0:1 192.168.1.110 broadcast 192.168.1.255 netmask 255.255.255.0 up  

  route add -host 192.168.1.110 dev eth0:1


2,  啟動,關閉keepalived :

 service keepalived start

 service keepalived stop

3,測試可用性:

①主Nginx停止Nginx或直接斷網情況下(backup正常),訪問虛擬IP:192.168.1.110的相關Web服務,正常,測試通過

②backup Nginx停止Nginx或直接斷網情況下(Master正常),訪問虛擬IP:192.168.1.110的相關Web服務,正常,測試通過




                                                     Nginx之反向代理



在配置nginx反向代理之間我們得先准備兩台測試服務器,Web1與Web2。
1.安裝httpd


[root@web1 ~]# yum install -y httpd
[root@web2 ~]# yum install -y httpd
2.提供測試頁面


[root@web1 ~]# echo "

web1.test.com

" > /var/www/html/index.html
[root@web2 ~]# echo "

web2.test.com

" > /var/www/html/index.html
3.啟動httpd服務


[root@web1 ~]# service httpd start
正在啟動 httpd:                                           [確定]
[root@web2 ~]# service httpd start
正在啟動 httpd:                                           [確定]

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。     

如下例:


location / {
  proxy_pass        http://localhost:8000;
  proxy_set_header  X-Real-IP  $remote_addr;
}
注意, 當使用http proxy模塊(甚至FastCGI),所有的連接請求在發送到后端服務器之前nginx將緩存它們,因此,在測量從后端傳送的數據時,它的進度顯示可能不正確。
實驗拓撲:
nginx4
7. 配置http反向代理


[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.重新加載一下配置文件

[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服務器日志


[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配置文件

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.重新加載一下配置文件

[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.測試並查看日志


[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

注,大家可以這里記錄日志的參數還是%h,下面我們修改一下參數
t5

注,這是修改后的參數,將h%修改為%{X-Real-IP}i,好的下面我們再來測試一下。

t6
15.重啟並測試

[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 負載均衡模塊說明

案例:

下面設定負載均衡的服務器列表。

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負載均衡

[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.重新加載一下配置文件


[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:

[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服務器記錄日志的格式。
[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:                                           [確定]
接着,再訪問多次,繼續查看日志。

[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一起使用,進行健康狀態檢查。


[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.重新加載一下配置文件

[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.停止服務器並測試

先停止Web1,進行測試。
[root@web1 ~]# service httpd stop
停止 httpd:                                               [確定]

t8
注,大家可以看到,現在只能訪問Web2,再重新啟動Web1,再次訪問一下。


[root@web1 ~]# service httpd start
正在啟動 httpd:                                           [確定] 

t7
t8

注,大家可以看到,現在又可以重新訪問,說明nginx的健康狀態查檢配置成功。但大家想一下,如果不幸的是所有服務器都不能提供服務了怎么辦,用戶打開頁面就會出現出錯頁面,那么會帶來用戶體驗的降低,所以我們能不能像配置LVS是配置sorry_server呢,答案是可以的,但這里不是配置sorry_server而是配置backup。

12.配置backup服務器


[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

Sorry......



13.重新加載配置文件

[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服務器並進行測試

[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共享問題。(一般電子商務網站用的比較多)

[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.重新加載一下服務器

[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的訪問連接數

[root@web2 ~]# netstat -an | grep :80 | wc -l
304
注,你不斷的刷新,連接數會越來越多。好了,nginx的負載均衡就全部演示到這里下面我們來說一說,頁面緩存。
六、 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參數指定緩存的子目錄數,例如:

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

文件名類似於:

/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指的是共享池的大小。
 
注意 每一個定義的內存池必須是不重復的路徑,例如:

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  

為不同的應答設置不同的緩存時間,例如:

proxy_cache_valid  200 302  10m;
proxy_cache_valid  404      1m;

為應答代碼為200和302的設置緩存時間為10分鍾,404代碼緩存1分鍾。 

如果只定義時間:

proxy_cache_valid 5m;

那么只對代碼為200, 301和302的應答進行緩存。  

同樣可以使用any參數任何應答。

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

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

[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.新建緩存目錄

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

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 命中

[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.重新加載一下配置文件

[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.查看一下緩存目錄

[root@nginx ~]# cd /data/nginx/cache/webserver/f/63/
[root@nginx 63]# ls
681ad4c77694b65d61c9985553a2763f
注,緩存目錄里確實有緩存文件。好了,nginx緩存配置就到這邊了,更多配置請根據需要看配置文檔。下面我們來說一下,URL重寫。


七、Nginx之URL重寫

1.URL重寫模塊(Rewrite)
摘要
這個模塊允許使用正則表達式重寫URI(需PCRE庫),並且可以根據相關變量重定向和選擇不同的配置。

如果這個指令在server字段中指定,那么將在被請求的location確定之前執行,如果在指令執行后所選擇的location中有其他的重寫規則,那么它們也被執行。

如果在location中執行這個指令產生了新的URI,那么location又一次確定了新的URI。這樣的循環可以最多執行10次
,超過以后nginx將返回500錯誤。

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

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來引用。  

示例配置:

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)。例如:


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錯誤。


location /download/ {
  rewrite  ^(/download/.*)/media/(.*)\..*$  $1/mp3/$2.mp3  break;
  rewrite  ^(/download/.*)/audio/(.*)\..*$  $1/mp3/$2.ra   break;
  return   403;
}
如果替換字段中包含參數,那么其余的請求參數將附加到后面,為了防止附加,可以在最后一個字符后面跟一個問號:

rewrite  ^/users/(.*)$  /show?user=$1?  last;
注意:大括號({和}),可以同時用在正則表達式和配置塊中,為了防止沖突,正則表達式使用大括號需要用雙引號(或者單引號)。例如要重寫以下的URL:

/photos/123456
為:

/path/to/photos/12/1234/123456.png
則使用以下正則表達式(注意引號):

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:

server {
   server_name www.example.com;
   rewrite ^ http://example.com$request_uri? permanent;
}
同樣,重寫只對路徑進行操作,而不是參數,如果要重寫一個帶參數的URL,可以使用以下代替:

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指令在配置文件加載時已經編譯到內部代碼中,在解釋器產生請求時使用。  
這個解釋器是一個簡單的堆棧虛擬機,如下列指令:

location /download/ {
  if ($forbidden) {
    return   403;
  }
  if ($slow) {
    limit_rate  10k;
  }
  rewrite  ^/(download/.*)/media/(.*)\..*$  /$1/mp3/$2.mp3  break;
將被編譯成以下順序:


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。  
指令:


rewrite  ^/(download/.*)/media/(.*)\..*$  /$1/mp3/$2.mp3  break;
如果我們將第一個斜杠括入圓括號,則可以減少執行順序:


rewrite  ^(/download/.*)/media/(.*)\..*$  $1/mp3/$2.mp3  break;
之后的順序類似如下:


checking regular excodession
copying $1
copying "/mp3/"
copying $2
copying ".mp3"
completion of regular excodession
completion of entire code
2.簡單案例
注,由於配置文件內容較多,為了讓大家看着方便,我們備份一下配置文件,打開一個新的配置文件。


[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目錄與測試文件


[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

forum page!


測試一下



注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com