nginx反向代理+快取開啟+url重寫+負載均衡(帶健康探測)的部署記錄

散盡浮華發表於2016-09-18

 

在日常運維工作中,運維人員會時常使用到nginx的反向代理,負載均衡以及快取等功能來優化web服務效能。
廢話不多說,下面對測試環境下的nginx反向代理+快取開啟+url重寫+負載均衡(帶健康探測)搭建過程做一記錄:

一、後端的Real Server的準備

兩臺RS伺服器(192.168.1.104/192.168.1.105)要事先配置好nginx。
並且nginx訪問均是用ip訪問即可,方便實驗效果!

二、nginx代理伺服器192.168.1.103(假設外網ip是111.112.114.23)的配置

1.nginx反向代理和快取

0)安裝依賴軟體(如果是ubuntu系統,則sudo apt-get update && sudo apt-get upgrade && sudo apt-get install libpcre3 libpcre3-dev zlib1g-dev libssl-dev build-essential openssl libssl0.9.8 libssl-dev)
[root@node1 ~]# yum install -y pcre pcre-devel openssl openssl-devel gcc

1)首先新增使用者nginx,實現以之執行nginx服務程式:
[root@node1 ~]# groupadd -r nginx
[root@node1 ~]# useradd -r -g nginx -s /bin/false -M nginx                  #-M參數列示建立使用者時不建立使用者家目錄

2)接著開始編譯和安裝:
[root@node1 ~]# cd /usr/loca/src
[root@node1 src]# wget http://nginx.org/download/nginx-1.8.0.tar.gz
[root@node1 src]# tar -zxvf nginx-1.8.0.tar.gz
[root@node1 src]# cd nginx-1.8.0
[root@node1 nginx-1.8.0]# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_flv_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre
[root@node1 src]# make && make install

#以上編譯安裝nginx後,--http-client-body-temp-path、--http-proxy-temp-path、--http-fastcgi-temp-path、--http-uwsgi-temp-path、--http-scgi-temp-path預設的路徑就在/usr/local/nginx下,分別是client_body_temp、proxy_temp、fastcgi_temp、scgi_temp、uwsgi_temp

[root@node1 src]# cd /usr/local/nginx/
[root@node1 nginx]# ls
conf html logs sbin
[root@node1 nginx]# /usr/local/nginx/sbin/nginx     //nginx啟動後,就會出現下面的目錄
[root@node1 nginx]# ls /usr/local/nginx/
client_body_temp conf fastcgi_temp html logs proxy_temp sbin scgi_temp uwsgi_temp

3)反代的實現,和快取的開啟(可參考:nginx快取配置的操作記錄梳理

[root@node1 src]# vim /usr/local/nginx/conf/nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
  keepalive_timeout 65;

#要想開啟nginx的快取功能,需要新增此處的兩行內容!

#這一行分別表示:定義快取儲存目錄,手動建立;快取級別,表示快取目錄的第一級目錄是1個字元,第二級目錄是2個字元;核心中建立用於快取快取資料來源資料的空間,查詢快取的時候,先從這個核心空間中找到,快取資料的源資料,然後再到對應目錄中查詢快取;這一行分別表示:快取空間最大值;快取的資料,60分鐘內沒有被訪問過就刪除 
  proxy_cache_path /var/www/cache levels=1:2 keys_zone=mycache:20m max_size=2048m inactive=60m;

#這一行分別表示:建立快取的時候可能生成一些臨時檔案存放的位置,自動建立
  proxy_temp_path /var/www/cache/tmp;

server {
listen 80;
server_name localhost;

location / {
#root html;
#index index.html index.htm;
  proxy_pass http://192.168.1.104/;                       #代理哪個web伺服器
  proxy_cache mycache;                                          #記憶體快取源資料空間名字,對應我們前面的設定
  proxy_cache_valid 200 302 60m;                          #頁面返回碼為200 302 的快取60分
  proxy_cache_valid 404 1m;                                   #頁面錯誤響應嗎404快取時間1分
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
  }

[root@node1 src]# mkdir /var/www/cache
[root@node1 src]# /usr/local/nginx/sbin/nginx

4)驗證結果
訪問http://111.112.114.23,則顯示的是http://192.168.1.104的訪問結果(如上配置,RS2的反向代理類似)

---------------------------------------------------------------------------------------------------------
再看如下的一個例項配置(nginx.conf檔案中已開啟快取功能)(max_fails預設值為1,fail_timeout預設值為10s,連線失敗的情形由proxy_next_upstream 指定)

upstream LB-WWW {
      ip_hash;
      server 192.168.1.101:80 max_fails=3 fail_timeout=30s weight=100;   #max_fails = 3 為允許失敗的次數,預設值為1
      server 192.168.1.102:80 max_fails=3 fail_timeout=30s weight=100;   #fail_timeout = 30s(也可以是fail_timeout = 30,即後面的秒單位不帶) 當max_fails次失敗後,暫停將請求分發到該後端伺服器的時間
      server 192.168.1.118:80 max_fails=3 fail_timeout=30s weight=50;    #由於這三臺機器中,前兩臺配置高,後一臺118機器配置低點,三臺機器開啟的nginx線上數是一樣的,所以118機器設定的weight權重低。
    }                                                                    #weight許可權設定低,命中率就會低,這樣機器壓力就會減輕(若是權重不設定低點,也可以通過減少nginx執行緒數來減少機器壓力);


server {
     listen       80;
     server_name  www.wangshibo.com;
  
      access_log  /usr/local/nginx/logs/www-access.log main;
      error_log  /usr/local/nginx/logs/www-error.log;
  
     location / {
         proxy_pass http://LB-WWW;
         proxy_redirect off ;
         proxy_set_header Host $host;
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header REMOTE-HOST $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_connect_timeout 300;             #跟後端伺服器連線超時時間,發起握手等候響應時間
         proxy_send_timeout 300;                #後端伺服器回傳時間,就是在規定時間內後端伺服器必須傳完所有資料
         proxy_read_timeout 600;                #連線成功後等待後端伺服器的響應時間,已經進入後端的排隊之中等候處理
         proxy_buffer_size 256k;                #代理請求緩衝區,會儲存使用者的頭資訊以供nginx進行處理
         proxy_buffers 4 256k;                  #同上,告訴nginx儲存單個用幾個buffer最大用多少空間
         proxy_busy_buffers_size 256k;          #如果系統很忙時候可以申請最大的proxy_buffers
         proxy_temp_file_write_size 256k;       #proxy快取臨時檔案的大小
         proxy_next_upstream error timeout invalid_header http_500 http_503 http_404;
         proxy_max_temp_file_size 128m;
         proxy_cache mycache;                   #記憶體快取源資料空間名字,對應我們前面的設定                      
         proxy_cache_valid 200 302 60m;                      
         proxy_cache_valid 404 1m;
        }
}

proxy_set_header引數解釋

1)proxy_redirect off
語法:proxy_redirect [ default|off|redirect replacement ] 
預設值:proxy_redirect default 
使用欄位:http, server, location 

proxy_redirect功能比較強大,其作用是對傳送給客戶端的URL進行修改。
如果需要修改從被代理伺服器傳來的應答頭中的"Location"和"Refresh"欄位,可以用這個指令設定。
設定為off,表示禁止所有的proxy_redirect指令.

假設被代理伺服器返回Location欄位為:http://localhost:8000/two/some/uri/
這個指令: 
proxy_redirect http://localhost:8000/two/ http://frontend/one/;
將Location欄位重寫為http://frontend/one/some/uri/。
在代替的欄位中可以不寫伺服器名:

proxy_redirect http://localhost:8000/two/ /;
這樣就使用伺服器的基本名稱和埠,即使它來自非80埠。
如果使用“default”引數,將根據location和proxy_pass引數的設定來決定。

例如下列兩個配置等效:
location /one/ {  
    proxy_pass  http://upstream:port/two/;  
    proxy_redirect   default;
} 

location /one/ {  
    proxy_pass  http://upstream:port/two/;  
    proxy_redirect  http://upstream:port/two/ /one/;
  }


在指令中可以使用一些變數:
proxy_redirect  http://localhost:8000/ http://$host:$server_port/;


這個指令有時可以重複:
proxy_redirect   default;  
proxy_redirect   http://localhost:8000/  /;  
proxy_redirect   ;  
/;

引數off將在這個欄位中禁止所有的proxy_redirect指令:
proxy_redirect   off;  
proxy_redirect   default;  
proxy_redirect   http://localhost:8000/  /;  
proxy_redirect   ;  
/;
利用這個指令可以為被代理伺服器發出的相對重定向增加主機名:

---------------------------------------------------------------------------------------------------
例項說明:
比如在做nginx反向代理時出了一點點問題,原來後端節點用的埠是8080,通過反向代理後,使用wireshark抓包發現location頭域數值為http://192.168.1.154:8080/huihui/,
如果把這個返回給客戶端肯定是不可以的,看起來彆扭而且還暴露了後端節點的具體資訊。所以在這裡用到了nginx的proxy_redirect指定修改被代理伺服器返回的響應頭中的location頭域跟refresh頭域數值。

前期配置(暴露了後端節點資訊)
[root@localhost nginx]# cat test.conf
server {
       listen       80;
       server_name  www.wangshibo.com;
       location / {
            proxy_pass http://192.168.1.154:8080;
            proxy_redirect off;
       }
 }

此時我們通過curl檢視結果得出
[root@localhost nginx]# curl -I http://www.wangshibo.com/huihui
HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Thu, 24 Dec 2015 12:02:00 GMT
Content-Type: text/html; charset=iso-8859-1
Connection: keep-alive
Location: http://192.168.1.154:8080/huihui/

這裡location為帶有後端伺服器實際地址跟埠的響應頭資訊,這樣在實際線上是不允許的。
所以這裡需要通過proxy_redirect將被代理伺服器的響應頭中的location欄位進行修改後返回給客戶端
修改後的配置:
[root@localhost nginx]# cat test.conf
server {
       listen       80;
       server_name  www.wangshibo.com;
       location / {
            proxy_pass http://192.168.1.154:8080;
            proxy_redirect http://192.168.1.154:8080/huihui/  http://www.wangshibo.com/huihui/;
       }
server {
       listen       80;
       server_name  www.wangshibo.com;
       location / {
            proxy_pass http://192.168.1.154:8080;
            proxy_redirect ~^http://192.168.1.154:8080(.*)   http://www.wangshibo.com$1;
       }
則curl檢視返回結果
[root@localhost nginx]# curl -I http://www.wangshibo.com/huihui
HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Thu, 24 Dec 2015 12:08:34 GMT
Content-Type: text/html; charset=iso-8859-1
Connection: keep-alive
Location: http://www.wangshibo.com/huihui/
此時檢視location已經變成了我們想要的結果了。 此時通過replacement 301重定向到了我們新的頁面
---------------------------------------------------------------------------------------------------

2)proxy_set_header Host $host;
允許重新定義或新增欄位傳遞給代理伺服器的請求頭。該值可以包含文字、變數和它們的組合。在沒有定義proxy_set_header時會繼承之前定義的值。
預設情況下,只有兩個欄位被重定義:
proxy_set_header Host       $proxy_host;
proxy_set_header Connection close;

例項說明:
nginx對於upstream預設使用的是基於IP的轉發,如下配置:
[root@localhost nginx]# cat test.conf
upstream backend {  
    server 127.0.0.1:8080;  
}  
upstream china {  
    server china.wangshibo.com;  
}  
server {  
        listen       80;  
        server_name  www.wangshibo.com;  
        proxy_set_header Host $http_host;  
        proxy_set_header x-forwarded-for  $remote_addr;  
        proxy_buffer_size         64k;  
        proxy_buffers             32 64k;  
        charset utf-8;  
  
        access_log  logs/host.access.log  main;  
        location = /50x.html {  
            root   html;  
        }  
    location / {  
        proxy_pass backend ;  
    }  
          
    location = /customer/straightcustomer/download {  
        proxy_pass http://china;  
        proxy_set_header Host $proxy_host;  
    }  
}  

當匹配到/customer/straightcustomer/download時,使用china處理,到upstream就匹配到china.wangshibo.com,這裡直接轉換成IP進行轉發了。
假如china.wangshibo.com是在另一臺nginx下配置的,ip為10.22.10.116,則$proxy_host則對應為10.22.10.116。
此時相當於設定了Host為10.22.10.116。如果想讓Host是china.wangshibo.com,則進行如下設定:
proxy_set_header Host china.wangshibo.com;

如果不想改變請求頭“Host”的值,可以這樣來設定:
proxy_set_header Host       $http_host;

但是,如果客戶端請求頭中沒有攜帶這個頭部,那麼傳遞到後端伺服器的請求也不含這個頭部。 這種情況下,更好的方式是使用$host變數——它的值在請求包含“Host”請求頭時為“Host”欄位的值,在請求未攜帶“Host”請求頭時為虛擬主機的主域名:
proxy_set_header Host       $host;

此外,伺服器名可以和後端伺服器的埠一起傳送:
proxy_set_header Host       $host:$proxy_port;

如果某個請求頭的值為空,那麼這個請求頭將不會傳送給後端伺服器:
proxy_set_header Accept-Encoding "";

3)有了下面三行配置,就可以在web的後端節點伺服器端獲得客戶端使用者的真實ip。
  proxy_set_header X-Real-IP $remote_addr;      //後端節點機器獲取客戶端真實ip的第一種方案
  proxy_set_header REMOTE-HOST $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;    //後端節點機器獲取客戶端真實ip的第二中方案。當然這兩種方案也可以一起配置!

其中這個X-real-ip是一個自定義的變數名,名字可以隨意取,這樣做完之後,使用者的真實ip就被放在X-real-ip這個變數裡了,然後,在web端可以這樣獲取:
request.getAttribute("X-real-ip")

remote_addr  代表客戶端的ip,但它的值不是由客戶端提供的,而是伺服器端根據客戶端的ip指定的,當你的瀏覽器訪問某個網站時,假設中間沒有任何代理,那麼網站的web伺服器(比如nginx)就會把remote_addr設定為
你的機器ip;如果你使用了代理,那麼你的瀏覽器會先訪問這個代理,然後再由這個代理轉發到網站,這樣web伺服器就會把remote_addr設為這臺代理機器的ip。

x_forwarded_for  正如上面所述,當你使用了代理時,web伺服器就不知道你的真實ip了。為了避免這個情況,代理伺服器通常會增加一個叫做x_forwarded_for的頭訊息,把連線它的客戶端ip(即你的上網機器的ip)
加到這個頭訊息裡,這樣就能保證網站的web伺服器能獲得真實ip。

使用haproxy做反向代理
通常網站為了支撐更大的訪問,會增加很多web伺服器,並在這些伺服器前面增加一個反向代理(如haproxy)它可以把負載均衡的分佈到這些伺服器上。你的瀏覽器訪問的首先是這臺反向代理伺服器,它再把
你的請求轉發到後面的web伺服器上,這就使得web伺服器會把remote_addr設為這臺反向代理伺服器的ip,為了能讓你的程式獲得真實的客戶端ip,就需要給haproxy增加下面的配置:
option  forwardfor
它的作用就像上面說的,增加一個x_forwarded_for的頭資訊,把你上網機器的ip新增進去。

-----------------------------------------------------------
實際上要獲得使用者的真實ip,不是隻有這一個方法,下面我們繼續看
proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
這裡有個X-Forwarded-For變數,這是一個squid開發的,用於識別通過HTTP代理或負載平衡器原始IP一個連線到Web伺服器的客戶機地址的非rfc標準,如果有做X-Forwarded-For設定的話,
每次經過proxy轉發都會有記錄,格式就是client1, proxy1, proxy2,以逗號隔開各個地址,由於他是非rfc標準,所以預設是沒有的,需要強制新增,在預設情況下經過proxy轉發的請求,
在後端看來遠端地址都是proxy端的ip 。也就是說在預設情況下我們使用request.getAttribute("X-Forwarded-For")獲取不到使用者的ip,如果我們想要通過這個變數獲得使用者的ip,
這樣配置的意思是:
增加一個$proxy_add_x_forwarded_for到X-Forwarded-For裡去,注意是增加,而不是覆蓋,當然由於預設的X-Forwarded-For值是空的,所以我們總感覺X-Forwarded-For的值就等於$proxy_add_x_forwarded_for的值,
實際上當你搭建兩臺nginx在不同的ip上,並且都使用了這段配置,那你會發現在web伺服器端通過request.getAttribute("X-Forwarded-For")獲得的將會是客戶端ip和第一臺nginx的ip。

那麼$proxy_add_x_forwarded_for又是什麼?
$proxy_add_x_forwarded_for變數包含客戶端請求頭中的"X-Forwarded-For",與$remote_addr兩部分,他們之間用逗號分開。

舉個例子,有一個web應用,在它之前通過了兩個nginx轉發,www.linuxidc.com 即使用者訪問該web通過兩臺nginx。
在第一臺nginx中,使用
proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
現在的$proxy_add_x_forwarded_for變數的"X-Forwarded-For"部分是空的,所以只有$remote_addr,而$remote_addr的值是使用者的ip,於是賦值以後,X-Forwarded-For變數的值就是使用者的真實的ip地址了。

到了第二臺nginx,使用
proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
現在的$proxy_add_x_forwarded_for變數,X-Forwarded-For部分包含的是使用者的真實ip,$remote_addr部分的值是上一臺nginx的ip地址,於是通過這個賦值以後現在的X-Forwarded-For的值就變成了“使用者的真實ip,
第一臺nginx的ip”,這樣就清楚了吧。最後我們看到還有一個$http_x_forwarded_for變數,這個變數就是X-Forwarded-For,由於之前我們說了,預設的這個X-Forwarded-For是為空的,
所以當我們直接使用proxy_set_header   X-Forwarded-For $http_x_forwarded_for時會發現,web伺服器端使用request.getAttribute("X-Forwarded-For")獲得的值是null。如果想要通過request.getAttribute("X-Forwarded-For")獲得使用者ip,就必須先使用proxy_set_header            
X-Forwarded-For $proxy_add_x_forwarded_for;這樣就可以獲得使用者真實ip。

---------------------------------------------------------------------------------------------------------

2.url的重寫

-----------------------------------------------------------------------------
介紹下url重寫的格式,寫在配置檔案中

rewrite regex replacement [flag]

Regex:被代替的原URL路徑,可以是莫須有的,不存在的,支援正規表示式
Replacement:用來實現代替的URL路徑,必須真實存在的
Flag:標誌位,定義URL重寫後進行的操作,有4種,分別是:

a)
last:匹配重寫後的URL,再一次對URL重寫規則進行匹配,當使用last的需要注意的是如下:

rewrite /images/.*\.jpg /images/a.jpg last;
這樣寫的話,將會造成死迴圈。

b)
break:匹配重寫URL後,終止匹配,直接使用

c)
redirect:臨時重定向,返回程式碼302

d)
permanent:永久重定向,返回程式碼301

-----------------------------------------------------------------------------

下面是nginx配置檔案中的配置,簡單實現url的重寫配置(可以在vhosts虛擬主機配置裡設定)
[root@node1 src]# vim /usr/local/nginx/conf/nginx.conf
...............

server {
listen 80;
server_name localhost;
root /var/www/html;
index index.html index.htm;

location / {
rewrite /abc http://www.huanqiu.com break;          #本機站點目錄下並不需要建立abc這個目錄,對其的訪問都重寫到http://www.huanqiu.com
}                                                                       

location /text {
rewrite / http://china.huanqiu.com break;                #本機站點目錄下不需要建立text目錄,對其的訪問都重寫到http://china.huanqiu.com
}                                                                         

}

[root@node1 src]# mkdir /var/www/html/text

注意:
nginx的rewrite重寫規則後的url必須要是能在外網訪問的真實url!
這一點要和nginx的反向代理區別開,proxy_pass代理後的url可以是內網訪問,在內網之間代理!

3.nginx實現帶健康狀態檢測的負載均衡

nginx要能夠檢測後端nginx的健康狀態,需要新的模組,重新編譯nginx

模組的使用:healthcheck_nginx_upstreams-master.zip

下載模組,下載到本機的/usr/loca/src目錄下
下載地址:http://pan.baidu.com/s/1o8IrpbG
提取密碼:vp4y

[root@node1 ~]# cd /usr/local/src
[root@node1 src]# unzip healthcheck_nginx_upstreams-master.zip
[root@node1 src]# ll healthcheck_nginx_upstreams-master

接下來切換到nginx解壓目錄,打補丁~
[root@node1 src]# cd nginx-1.8.0
[root@node1 nginx-1.8.0]# patch -p1 < ../healthcheck_nginx_upstreams-master

然後重新編譯nginx,加上healthcheck_nginx_upstreams-master模組
[root@node1 nginx-1.8.0]# ./configure --prefix=/usr/loca/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_flv_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --add-module=/usr/local/src/healthcheck_nginx_upstreams-master

[root@node1 src]# make && make install

接下來配置實現nginx帶健康狀態的負載均衡:
[root@node1 src]# vim /usr/local/nginx/conf/nginx.conf
..................
..................
upstream cluster {
   server 192.168.1.104 weight=1;
 server 192.168.1.105 weight=1;
  
 healthcheck_enabled;
 healthcheck_delay 1000;
 healthcheck_timeout 1000;
 healthcheck_failcount 3;
   healthcheck_send "GET /.health HTTP/1.0";
 
 #healthcheck_expected 'I_AM_ALIVE';       #從RS上收到的http body部分的響應內容,如果未設定,則表示從後端伺服器收到200狀態碼即可,這裡我們不啟用 
   # Optional supervisord module support
   #supervisord none;
   #supervisord_inherit_backend_status;
}

server {
listen 80;

server_name localhost;

location / {
root html;
index index.php index.html index.htm;
proxy_pass http://cluster;

}
location /stat {
healthcheck_status;
}
}

----------------------------------------------------------------------------------------
上面引數解釋:
upstream cluster                                                //定義後方的伺服器群組
Server 192.168.1.104 weight=1                       //指明後方的一臺伺服器地址,權重設定為1;也可以IP:PORT指定埠實現埠對映
Server 192.168.1.105 weight=1                      //指明後方的另一臺伺服器地址,權重設定為1

healthcheck_enable                                         //開啟健康探測功能
healthcheck_delay 1000                                  //設定健康檢測的時延;即對同一臺RS兩次檢測之間的時間間隔,單位毫秒,預設為1000 
healthcheck_timeout 1000                              //設定一次健康檢測的超時時間
healthcheck_failcount 1                             //後方某臺伺服器有一次檢測不到即視為宕掉;即對同一臺RS檢測成功或失敗多少次,才決定其成功或失敗,並實現啟用和禁用此服務
healthcheck_send "GET /.health HTTP/1.0"    //使用GET方法訪問後方伺服器站點下的.health來進行探測;即從RS上獲得用於檢測健康狀態的檔案,預設只支援http 1.0協議 

proxy_pass http://cluster                                  //與upstream cluster相對應,在訪問http://111.112.114.23時將流量轉發到cluster組內機器上

location /stats                                                 //定義一個站點,用來檢視後方伺服器的健康狀況
----------------------------------------------------------------------------------------

最後,重啟nginx
[root@node1 src]# /usr/local/nginx/sbin/nginx -s reload

測試:
假如:
RS1機器上訪問的結果是“welcome to 192.168.1.104”
RS2機器上訪問的結果是“welcome to 192.168.1.105”

訪問http://111.112.114.23,第一次出現的如果是RS1的訪問結果,那麼再刷一下,就會出現RS2的訪問結果,這樣就看出了負載均衡的效果。 

可以檢視後端兩臺Real Server伺服器的健康狀態:
訪問http://111.112.114.23/stat即可!

關閉RS1的nginx服務,再次訪問http://111.112.114.23/stat檢視後端機器狀態,就會發現RS1的健康狀態已提示Bad,即顯示後端的192.168.1.101的RS1不能正常連線。

這樣就實現了負載均衡和健康探測,但依然不能滿足高併發量,再次用ab進行測試:

但是,這樣通過nginx代理可以滿足的最大連線請求依然沒有直接訪問RS的大!
這個通過下面結果可知:
[root@node1 src]# ab -c 100 -n 10000 http://192.168.1.104/test.jpg

[root@node1 src]# ab -c 100 -n 10000 http://111.112.114.23/test.jpg

繼續做優化!如下:
[root@node1 src]# vim /usr/local/nginx/conf/nginx.conf
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
  keepalive_timeout 65;

proxy_cache_path /var/www/cache levels=1:2 keys_zone=mycache:20m max_size=2048m inactive=24h;

proxy_temp_path /var/www/cache/tmp; 

upstream cluster {
   server 192.168.1.104 weight=1;
 server 192.168.1.105 weight=1;
 healthcheck_enabled;
 healthcheck_delay 1000;
 healthcheck_timeout 1000;
 healthcheck_failcount 3;
   healthcheck_send "GET /.health HTTP/1.0";

}

server {
listen 80;
server_name localhost;

location / {
root html;
index index.php index.html index.htm;
proxy_set_header HOST $host;
proxy_cache STATIC;
proxy_cache_valid 200 1d;
proxy_cache_use_stale error_timeout invalid_header updating http_500 http_502 http_503 http_504;
proxy_pass http://cluster;

}
location /stat {
healthcheck_status;
}
}

--------------------------------------------------------------
引數解釋:
proxy_cache_path     //設定快取的路徑和其他引數。快取資料是儲存在檔案中的,快取的鍵和檔名都是在代理URL上執行MD5的結果。 levels引數定義了快取的層次結構。

proxy_set_header     //允許重新定義或者新增發往後端伺服器的請求頭。

proxy_cache             //指定用於頁面快取的共享記憶體。

proxy_cache_valid    //為不同的響應狀態碼設定不同的快取時間。

proxy_cache_use_stale    //指定後端伺服器出現狀況時,nginx可以使用的過期快取
---------------------------------------------------------------

接著重啟nginx服務
[root@node1 src]# /usr/local/nginx/sbin/nginx -s reload

[root@node1 src]# mkdir /var/www/cache            #這個前面做快取時,已經建立了。

再次進行壓力測試,可以看到通過nginx代理可以滿足的最大連線請求已經達到了5000多,超過了直接訪問RS的最大連線請求了!

這樣負載均衡+健康探測+快取已經完成!

[root@node1 src]# ab -c 100 -n 10000 http://111.112.114.23/test.jpg

接下來一個問題就是在啟用快取之後的訪問問題,試著重新訪問一下該站點http://111.112.114.23:

即第一次訪問http://111.112.114.23時訪問到了192.168.1.104(即RS1),顯示結果是:“welcome to 192.168.1.104”,前端nginx將本次的訪問結果放入本地快取,在快取未失效之前,訪問http://111.112.114.23時實際上是nginx的本地快取提供的訪問結果,依然顯示“welcome to 192.168.1.104”的頁面。
可以試著多重新整理幾次,可以發現再怎麼重新整理頁面內容依然是“welcome to 192.168.1.104”!
這就證明現在訪問到的是nginx快取在本地的結果!

看看快取目錄中有沒有內容
[root@node1 src]# ll /var/www/cache                   #發現快取目錄下已經有了快取結果;可以將這個快取結果清除,再次刷次頁面,就會是新頁面了。
total 4
drwx------ 3 nginx nginx 4096 Sep 18 16:44 e
[root@node1 src]#

相關文章