nginx的web快取服務環境部署記錄

散盡浮華發表於2016-12-19

 

web快取位於內容源Web伺服器和客戶端之間,當使用者訪問一個URL時,Web快取伺服器會去後端Web源伺服器取回要輸出的內容,然後,當下一個請求到來時,如果訪問的是相同的URL,Web快取伺服器直接輸出內容給客戶端,而不是向源伺服器再次傳送請求.Web快取降低了內容源Web伺服器,資料庫的負載,減少了網路延遲,提高了使用者訪問的響應速度,增強了使用者體驗.

web快取伺服器中,最著名的要數Squid Cache(簡稱為Squid),Squid是一個流浪的自由軟體的代理伺服器和Web快取伺服器。
----------------------------------------------------------------------------------------------------------------------------
Squid可以作為網頁伺服器的前置cache伺服器快取相關請求來提高Web伺服器的速度;
Squid可以為一組人共享網路資源而快取全球資訊網,域名系統和其他網路搜尋;
Squid可以通過過濾流量幫助網路安全,到區域網通過代理上網.
----------------------------------------------------------------------------------------------------------------------------
然而,當下多數公司網站的圖片,js,css等檔案的快取會選擇Nginx的web快取服務。

如下將對nginx的web快取功能的整體配置進行梳理性記錄:
Nginx的Web快取服務主要由proxy_cache相關指令集和fastcgi_cache相關指令集構成。
1)proxy_cache相關指令集用於反向代理時,對後端內容源伺服器進行快取.Nginx的proxy_cache快取功能,十分穩定,速度不遜於Squid!

2)fastcgi相關指令集主要用於對FastCGI的動態程式進行快取.兩者功能基本一樣.在功能上,Nginx已經具備Squid所擁有的Web快取加速功能,清除指定URL快取功能.而在效能上,Nginx對多核CPU的利用,勝過Squid不少.另外,在反向代理,負載均衡,健康檢查,後端伺服器故障轉移,重寫,易用性上,Nginx也比Squid強大很多.這使得一臺Nginx可以同時作為"負載均衡伺服器"與"Web快取伺服器"來使用.

proxy_cache相關指令集
(1)proxy_cache指令
語法: proxy_cache zone_name ;
該指令用於設定哪個快取區將被使用,zone_name的值為proxy_cache_path指令建立的快取區的名稱。proxy_pass 指定獲取靜態內容的地址,其實proxy_cache的原理就是從一個指定的地址獲取內容,然後快取。當下次訪問時,nginx會自動判斷有沒有快取檔案?如果有的話快取檔案是不是已經過期。

(2)proxy_cache_path指令
語法 proxy_cache_path path [levels=number]

keys_zone=zone_name:zone_size[inactive=time] [max_size=size];
該指令用於設定快取檔案的存放路徑.

例如:
proxy_cache_path /usr/local/nginx/proxy_cache_dir levels=1:2 keys_zone=cache_one:500m inactive=1d max_size=30g ;
解釋:
path 表示存放目錄
levels 表示指定該快取空間有兩層hash目錄,第一層目錄為1個字母,第二層目錄為2個字母,
儲存的檔名會類似/usr/local/nginx/proxy_cache_dir/c/29/XXXXXX ;
keys_zone引數用來為這個快取區起名.
500m 指記憶體快取空間大小為500MB
inactive的1d指如果快取資料在1天內沒有被訪問,將被刪除。相當於expires過期時間的配置
max_size的30g是指硬碟快取空間為30G

(3)proxy_cache_methods指令
語法:proxy_cache_methods[GET HEAD POST];
該指令用於設定快取哪些HTTP方法,預設快取HTTP GET/HEAD方法,不快取HTTP POST 方法

(4)proxy_cache_min_uses指令
語法:proxy_cache_min_uses the_number
該指令用於設定快取的最小使用次數,預設值為1

(5)proxy_cache_valid指令
語法: proxy_cache_valid reply_code [reply_code...] time ;
該指令用於對不同返回狀態碼的URL設定不同的快取時間.
例如:
proxy_cache_valid 200 302 10m ;
proxy_cache_valid 404 1m ;
設定200,302狀態的URL快取10分鐘,404狀態的URL快取1分鐘.

(6)proxy_cache_key指令
語法: proxy_cache_key line ;
該指令用來設定Web快取的Key值,Nginx根據Key值md5雜湊儲存快取.一般根據$host(域名),$request_uri(請求的路徑)等變數組合成proxy_cache_key .

proxy_cache快取配置的完整示例(多數nginx快取的配置):
1)下載nginx和第三方的ngx_cache_purge模組的編譯安裝包(官網:http://labs.frickle.com/nginx_ngx_cache_purge/),將ngx_cache_purge編譯到到Nginx中,用來清除指定URL的快取
[root@test-huanqiu ~]# yum install -y pcre pcre-devel openssl openssl-devel gcc            //首先安裝依賴
[root@test-huanqiu ~]# cd /usr/local/src
[root@test-huanqiu src]# wget http://labs.frickle.com/files/ngx_cache_purge-2.3.tar.gz
[root@test-huanqiu src]# wget http://nginx.org/download/nginx-1.8.0.tar.gz
[root@test-huanqiu src]# tar -zxvf ngx_cache_purge-2.3.tar.gz
[root@test-huanqiu src]# tar zxvf nginx-1.8.0.tar.gz
[root@test-huanqiu src]# cd nginx-1.8.0.tar.gz
[root@test-huanqiu nginx-1.8.0]# ./configure --user=www --group=www --add-module=../ngx_cache_purge-2.3 --prefix=/usr/local/nginx --with-http_ssl_module --with-http_flv_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre
[root@test-huanqiu src]# make && make install

2)接著,在同一分割槽下建立兩個快取目錄,分別供proxy_temp_path , proxy_cache_path指令設定快取路徑.
注意:proxy_temp_path和proxy_cache_path指定的路徑必須在同一磁碟分割槽,決不能跨區分,因為它們之間是硬連結的關係,避免不通檔案系統之間的磁碟IO消耗。
[root@test-huanqiu src]# mkdir -p /usr/local/nginx/proxy_cache_path             #注意,這兩個目錄的許可權一定要是www.www,即是nginx程式許可權
[root@test-huanqiu src]# mkdir -p /usr/local/nginx/proxy_temp_path               #這是快取檔案的臨時存放目錄

3)在配置檔案nginx.conf中對副檔名為gif,jpg,jpeg,png,bmp,swf,js,css的圖片,flash,javascript , css檔案開啟Web快取,其他檔案不快取。

[root@test-huanqiu src]# vim /usr/local/nginx/conf/nginx.conf
user  www;
worker_processes  8;
 
events {
    worker_connections  65535;
}
 
http {
    include       mime.types;
    default_type  application/octet-stream;
    charset utf-8;

    log_format  main  '$http_x_forwarded_for $remote_addr $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_cookie" $host $request_time';
    sendfile       on;
    tcp_nopush     on;
    tcp_nodelay    on;
    keepalive_timeout  65;

#要想開啟nginx的快取功能,需要新增此處的兩行內容!
#設定Web快取區名稱為cache_one,記憶體快取空間大小為500M,快取的資料超過1天沒有被訪問就自動清除;訪問的快取資料,硬碟快取空間大小為30G
    proxy_cache_path /usr/local/nginx/proxy_cache_path levels=1:2 keys_zone=cache_one:500m inactive=1d max_size=30g;

#建立快取的時候可能生成一些臨時檔案存放的位置 
    proxy_temp_path /usr/local/nginx/proxy_temp_path; 

    fastcgi_connect_timeout 3000;
    fastcgi_send_timeout 3000;
    fastcgi_read_timeout 3000;
    fastcgi_buffer_size 256k;
    fastcgi_buffers 8 256k;
    fastcgi_busy_buffers_size 256k;
    fastcgi_temp_file_write_size 256k;
    fastcgi_intercept_errors on;
 
    
    client_header_timeout 600s;
    client_body_timeout 600s;
 
    client_max_body_size 100m;              
    client_body_buffer_size 256k;            
 
    gzip  on;
    gzip_min_length  1k;
    gzip_buffers     4 16k;
    gzip_http_version 1.1;
    gzip_comp_level 9;
    gzip_types       text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php;
    gzip_vary on;
 

    include vhosts/*.conf;
}

[root@test-huanqiu src]# ulimit -n 65535
[root@test-huanqiu src]# mkdir /usr/local/nginx/conf/vhosts

如果執行"nginx -t"檢查配置檔案的時候,報錯:
nginx: [emerg] unknown directive "  proxy_temp_path" in /usr/local/nginx/conf/nginx.conf:21
nginx: configuration file /usr/local/nginx/conf/nginx.conf test failed

nginx: [emerg] unknown directive "  proxy_cache_path" in /usr/local/nginx/conf/nginx.conf:21
nginx: configuration file /usr/local/nginx/conf/nginx.conf test failed

可能原因:nginx.conf裡關於這兩行的配置有誤,比如這兩行前面的空格有誤。可以先刪除空格,然後再空格鍵設定空格,防止不規範空格。

[root@test-huanqiu src]# vim /usr/local/nginx/conf/vhosts/wang.conf

upstream LB-WWW {
      ip_hash;
      server 192.168.1.101:80 max_fails=3 fail_timeout=30s;     #max_fails = 3 為允許失敗的次數,預設值為1
      server 192.168.1.102:80 max_fails=3 fail_timeout=30s;     #fail_timeout = 30s 當max_fails次失敗後,暫停將請求分發到該後端伺服器的時間
      server 192.168.1.118:80 max_fails=3 fail_timeout=30s;
    }
 
 
server {
     listen       80;
     server_name  www.wangshibo.com;
     index index.html index.php index.htm;
     root /var/www/html;

     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;
        }

     location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|js|css)$ {          
      #使用Web快取區cache_one,已在nginx.conf的快取配置中命名的。
      proxy_cache cache_one ;
      #對不同HTTP狀態碼快取設定不同的快取時間
      proxy_cache_valid 200 304 12h ;
      proxy_cache_valid 301 302 1m ;
      proxy_cache_valid any 1m ;
      #設定Web快取的Key值,Nginx根據Key值md5雜湊儲存快取,這裡根據"域名,URI,
      #引數"組合成Key
      proxy_cache_key $host$uri$is_args$args;
     }
 
    #用於清除快取的url設定
    #假設一個URL為http://www.wangshibo.com/test.gif,那麼就可以通過訪問http://www.wangshibo.com/purge/test.gif清除該URL的快取。
    location ~ /purge(/.*) {
      #設定只允許指定的IP或IP段才可以清除URL快取
      allow 127.0.0.1 ;
      allow 192.168.0.0/16 ;
      deny all ;
      proxy_cache_purge cache_one $host$1$is_args$args ;
    }

}

fastcgi_cache相關指令集
(1)fastcgi_cache指令
語法:fastcgi_cache zone_name;
該指令用於設定哪個快取區將被使用,zone_name的值為fastcgi_cache_path指令建立的快取區名稱.

(2)fastcgi_cache_path指令
語法:fastcgi_cache_path path [levels=number] keys_zone=zone_name:zone_size [inactive=time] [max_size=size];
該指令用於設定快取檔案的存放路徑,
例如:
fastcgi_cache_path /usr/local/nginx/fastcgi_cache_dir levels=1:2 keys_zone=cache_one:500m inactive=1d max_size=30g ;
注意這個指令只能在http標籤內配置,
levels指定該快取空間有兩層hash目錄,第一層目錄為1個字母,第二層為2個字母,儲存的
檔名會類似/usr/local/nginx/fastcgi_cache_dir/c/29/XXXX;
keys_zone引數用來為這個快取區起名,
500m指記憶體快取空間大小為500MB;
inactive的1d指如果快取資料在1天內沒有被訪問,將被刪除;
max_size的30g是指硬碟快取空間為30GB

(3)fastcgi_cache_methods指令
語法:fastcgi_cache_methods [GET HEAD POST] ;
該指令用於設定快取哪些HTTP方法,預設快取HTTP GET/HEAD 方法,不快取HTTP POST方法

(4)fastcgi_cache_min_uses指令
語法:fastcgi_cache_min_uses the_number;
該指令用於設定快取的最小使用次數,預設值為1.

(5)fastcgi_cache_valid指令
fastcgi_cache_valid reply_code [reply_code...] time;
該‎指令用於對不同返回狀態碼的URL設定不同的快取時間.
fastcgi_cache_valid 200 302 10m ;
fastcgi_cache_valid 404 1m ;
設定200,302狀態的URL快取10分鐘,404狀態的URL快取1分鐘.
如果不指定狀態碼,直接指定快取時間,則只有200,301,302狀態的URL快取5分鐘.

(6)fastcgi_cache_key指令
語法:fastcgi_cache_key line ;
該指令用來設定Web快取的Key值,Nginx根據Key值md5雜湊儲存快取.一般根據FastCGI伺服器的地址和埠,$request_uri(請求的路徑)等變數組合成fastcgi_cache_key。

fastcgi_cache快取配置的完整示例
1)首先,在同一分割槽下建立兩個快取目錄,分別供fastcgi_temp_path,fastcgi_cache_path指令設定快取路徑.
注意:兩個指定設定的快取路徑必須為同一磁碟分割槽,不能跨分割槽.
[root@test-huanqiu src]# mkdir -p /usr/local/nginx/fastcgi_temp_path
[root@test-huanqiu src]# mkdir -p /usr/local/nginx/fastcgi_cache_path
2)配置檔案nginx.conf對副檔名為gif,jpg,jpeg,png,bmp,swf,js,css的圖片,Flash,JavaScript,CSS檔案開啟Web快取,其他檔案不快取.

[root@test-huanqiu src]# vim /usr/local/nginx/conf/nginx.conf
........
http{
  #fastcgi_temp_path和fastcgi_cache_path指定的路徑必須在同一分割槽
  fastcgi_temp_path /usr/local/nginx/fastcgi_temp_path ;
  #設定Web快取區名稱為cache_one,記憶體快取空間大小為500MB,自動清除超過1天沒有被

  #訪問的快取資料,硬碟快取空間大小為30G
  fastcgi_cache_path /usr/local/nginx/fastcgi_cache_path levels=1:2 keys_zone=cache_one:200m inactive=1d max_size=30g ;
........
}
[root@test-huanqiu src]# vim /usr/local/nginx/conf/vhosts/wang.conf
  server{
  .......
    
    location ~ .*\.(php|php5)$ {
      #使用Web快取區cache_one
      fastcgi_cache cache_one ;
      #對不同的HTTP狀態碼快取設定不同的快取時間
      fastcgi_cache_valid 200 10m ;
      fastcgi_cache_valid 301 302 1h ;
      fastcgi_cache_valid an 1m ;
      #設定Web快取的key值,Nginx根據key值md5雜湊儲存快取,這裡根據"FastCGI服務  

    #器的IP,埠,請求的URI"組合成Key。
      fastcgi_cache_key 127.0.0.1:9000$requet_uri ;
      #FastCGI伺服器
      fastcgi_pass 127.0.0.1:9000 ;
      fastcgi_index index.php ;
      include fcgi.conf ;
    }
}

ngx_cache_purge 是 nginx 的第三方那個模組,用於清除 FastCGI, proxy, SCGI and uWSGI 快取,nginx預設安裝就會帶有反向代理的功能,但想要更好的使用,還得配備frickle.com的ngx_cache_purge模組,用於清除指定URL的快取。
proxy_cache和fastcgi_cache構成了Nginx的快取,proxy_cache主要用於反向代理時,對後端內容源伺服器進行快取fastcgi_cache主要用於對FastCGI的動態程式進行快取。兩者的功能基本上一樣。
-> proxy_cache的作用是快取後端伺服器的內容,可能是任何內容,包括靜態的和動態。
-> proxy_cache快取減少了nginx與後端通訊的次數,節省了傳輸時間和後端寬頻。
-> fastcgi_cache的作用是快取fastcgi生成的內容,很多情況是php生成的動態的內容。
-> fastcgi_cache快取減少了nginx與php的通訊的次數。

---------------------------------------------------------------------------------在單機上部署nginx的cache快取服務操作記錄-------------------------------------------------------------------

根據業務部門需求,申請一臺檔案的cache伺服器。如下記錄在單臺機器上部署Nginx快取服務過程:
nginx快取配置(快取配置的引數這裡就不做過多解釋了,在前面的文件中已說明過,這裡只做簡單記錄)
[root@storage01 ~]# cat /data/nginx/conf/nginx.conf|grep -v "^$"|grep -v "#"
user  www;
worker_processes  8;
  
events {
    worker_connections  65535;
}
  
http {
    include       mime.types;
    default_type  application/octet-stream;
    charset utf-8;
 
    log_format  main  '$http_x_forwarded_for $remote_addr $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_cookie" $host $request_time';
    sendfile       on;
    tcp_nopush     on;
    tcp_nodelay    on;
    keepalive_timeout  65;
 
    proxy_temp_path /data/nginx/proxy_temp;
    proxy_cache_path /data/nginx/proxy_cache levels=1:2 keys_zone=cache_one:500m inactive=1d max_size=30g;
     
    client_header_timeout 600s;
    client_body_timeout 600s;
  
    client_max_body_size 50m;             
    client_body_buffer_size 256k;           
  
    gzip  on;
    gzip_min_length  1k;
    gzip_buffers     4 16k;
    gzip_http_version 1.1;
    gzip_comp_level 9;
    gzip_types       text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php;
    gzip_vary on;
  
    include vhosts/*.conf;
}


注意:快取目錄/proxy_cache和/proxy_temp一定要在同一個分割槽下,並且許可權一定要和nginx程式許可權一致(即要有寫入許可權,否則不能生產快取檔案)!
[root@storage01 ~]# mkdir /data/nginx/proxy_cache
[root@storage01 ~]# mkdir /data/nginx/proxy_temp
[root@storage01 ~]# chown -R www.www /data/nginx/proxy_cache
[root@storage01 ~]# chown -R www.www /data/nginx/proxy_temp 
[root@storage01 ~]# chmod -R 777 /data/nginx/proxy_cache
[root@storage01 ~]# chmod -R 777 /data/nginx/proxy_temp 

[root@storage01 ~]# cat /data/nginx/conf/vhosts/8888.conf 
server {
     listen       8888;
     server_name  localhost;

     access_log  /data/nginx/logs/8888-access.log main;
     error_log  /data/nginx/logs/8888-error.log;

location / {
     index index.html index.htm;
     root /data/img/;
    }
}

[root@storage01 ~]# cat /data/nginx/conf/vhosts/img.conf 
upstream cache {
      server localhost:8888 max_fails=3 fail_timeout=30s;
    }

server {
     listen       80;
     server_name  img.wang.com;

     access_log  /data/nginx/logs/img-access.log main;
     error_log  /data/nginx/logs/img-error.log;

     location / {
         proxy_pass http://cache;
         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_next_upstream error timeout invalid_header http_500 http_503 http_404;

         proxy_cache cache_one ;
         proxy_cache_valid 200 304 12h ;
         proxy_cache_valid 301 302 1m ;
         proxy_cache_valid any 1m ;
         proxy_cache_key $host$uri$is_args$args;
        }
  
    location ~ /purge(/.*) {
      allow all ;
      proxy_cache_purge cache_one $host$1$is_args$args ;
      error_page 405 =200 /purge$1;
    }
}

訪問域名測試

[root@storage01 ~]# ll -d /data/img/
drwxr-xr-x 3 www www 4096 Aug 21 14:56 /data/img/
[root@storage01 ~]# ll /data/img/
total 8
-rwxr-xr-x 1 www www   31 Aug 16 15:44 index.html
drwxr-xr-x 2 www www 4096 Aug 21 14:57 upload
[root@storage01 ~]# cat /data/img/index.html 
快取伺服器!!!!!
[root@storage01 ~]# ll /data/img/upload/
total 140
-rw-r--r-- 1 www www 140935 Aug 17 09:31 test.jpg

檢視快取檔案

[root@storage01 ~]# ll /data/nginx/proxy_cache/
total 24
drwx------ 3 www www 4096 Aug 21 16:57 2
drwx------ 3 www www 4096 Aug 21 16:56 3
drwx------ 3 www www 4096 Aug 21 17:05 4
drwx------ 3 www www 4096 Aug 21 16:55 6
drwx------ 3 www www 4096 Aug 21 16:55 7
drwx------ 3 www www 4096 Aug 21 16:57 b
[root@storage01 ~]# ll /data/nginx/proxy_cache/2
total 4
drwx------ 2 www www 4096 Aug 21 16:57 fc
[root@storage01 ~]# ll /data/nginx/proxy_cache/3
total 4
drwx------ 2 www www 4096 Aug 21 17:08 05

上面快取檔案的結構是由levels=1:2決定的,即第一層目錄是一個字母命名,第二層目錄是兩個字母表示

快取檔案強磁碟打滿該怎麼辦?
由於寫入路徑為一個單一目錄,只能寫入一塊磁碟。一塊磁碟很快就會被打滿,解決該問題有如下兩種方法:
1)將多塊磁碟做磁碟陣列? 缺點是:減小了實際的儲存空間。
2)巧妙得運用proxy_cache_path的目錄結構,由於levels=1:2,這導致快取檔案的目錄結構為兩層,每層目錄名,都是由hash函式生成。
如上,可以將/data/nginx/proxy_cache/下的一級目錄通通軟連結到大空間的分割槽下。

如果nginx快取配置後,proxy_cache_path快取目錄下不能生成快取檔案的原因:

1)/data/nginx/proxy_cache和/data/nginx/proxy_temp的許可權問題(如上,這倆目錄許可權要是www.www,最好777許可權)
2)proxy_cache_valid和proxy_pass這兩條,就算在單機部署,也要通過proxy_pass代理到自己的對應訪問埠下。
proxy_pass指定獲取靜態內容的地址,其實proxy_cache的原理就是從一個你指定的地址獲取內容,然後快取。當下次你訪問時,nginx會自動判斷有沒有快取檔案?
如果有的話快取檔案是不是已經過期(快取檔案的有效期就是第一條設定的)?如果前面兩條任何一條成立就會從proxy_pass的地址重新獲取頁面資訊。

手動清除快取(用到模組ngx_cache_purge)。通過http://img.wang.com/purge/upload/test.jpg手動清理快取

再次訪問http://img.wang.com/purge/upload/test.jpg進行快取清理,由於上面已經清理過一次了,所以再次使用這個url進行清理的話,就會報404

需要再次訪問http://img.wang.com/upload/test.jpg(如果如上清理快取後,訪問這個失敗,就嘗試完全清理瀏覽器快取),就會再次生成快取,由此再可以使用上面的purge的url路徑進行快取清理!

[root@storage01 ~]# cd /data/nginx/proxy_cache/
[root@storage01 proxy_cache]# ll
total 8
drwx------ 3 www www 4096 Aug 21 17:23 3
drwx------ 3 www www 4096 Aug 21 17:23 b
[root@storage01 proxy_cache]# rm -rf ./*
[root@storage01 proxy_cache]# ll
total 0
[root@storage01 proxy_cache]# /data/nginx/sbin/nginx -s reload

然後訪問http://img.wang.com/upload/test.jpg,強制重新整理幾次。隨後就會發現快取檔案就會自動生成了!
[root@storage01 proxy_cache]# ll
total 8
drwx------ 3 www www 4096 Aug 21 17:26 3
drwx------ 3 www www 4096 Aug 21 17:26 b
[root@storage01 proxy_cache]# ll b
total 4
drwx------ 2 www www 4096 Aug 21 17:26 a1

--------------------------------------------------------------------------nginx代理中的緩衝快取優化說明------------------------------------------------------------------------

Nignx反向代理的一個問題是代理大量使用者時會增加伺服器程式的效能衝擊影響。在大多數情況下,可以很大程度上能通過利用Nginx的緩衝和快取功能減輕。
當代理到另一臺伺服器,兩個不同的連線速度會影響客戶的體驗:
-> 從客戶機到Nginx代理的連線。
-> 從Nginx代理到後端伺服器的連線。

Nginx具有優化這些連線調整其行為的能力。
-> 如果沒有緩衝,資料從代理的伺服器傳送並立即開始被髮送到客戶。如果假定客戶端很快,緩衝可以關閉而儘快使資料到客戶端.
-> 有了緩衝,Nginx代理將暫時儲存後端的響應,然後按需供給資料給客戶端。如果客戶端是緩慢的,允許Nginx伺服器關閉到後端的連線。然後,它可以處理資料分配到客戶端,以任何可能的速度。

Nginx預設有緩衝設計,因為客戶端往往有很大的不同的連線速度。可以用以下指令調節緩衝行為。可以在HTTP,server或location位置來設定。重要的是要記住,大小size指令是針對每個請求配置的,
所以增加超出你需求會影響你的效能,如果這時有許多客戶端請求:
1)proxy_buffering:該指令控制緩衝是否啟用。預設情況下,它的值是"on"。
2)proxy_buffers:該指令控制代理響應緩衝區的數量(第一個引數)和大小(第二個引數)。預設配置是8個緩衝區大小等於一個記憶體頁(4K或者8K)。增加緩衝區的數目可以讓你緩衝更多資訊。
3) proxy_buffer_size:從後端伺服器的響應頭緩衝區大小,它包含headers,和其他部分響應是分開的。該指令設定響應部分的緩衝區大小。預設情況下,它和proxy_buffers是相同的尺寸,
   但因為這是用於頭資訊,這通常可以設定為一個較低的值。
4)proxy_busy_buffers_size:此指令設定標註"client-ready"緩衝區的最大尺寸。而客戶端可以一次讀取來自一個緩衝區的資料,緩衝被放置在佇列中,批量傳送到客戶端。此指令控制允許是在這種狀態下的緩衝空間的大小。
5)proxy_max_temp_file_size:這是每個請求能用磁碟上臨時檔案最大大小。這些當上遊響應太大不能裝配到緩衝區時被建立。
6)proxy_temp_file_write_size:這是當被代理伺服器的響應過大時Nginx一次性寫入臨時檔案的資料量。
7)proxy_temp_path:當上遊伺服器的響應過大不能儲存到配置的緩衝區域時,Nginx儲存臨時檔案硬碟路徑。

Nginx提供了相當多不同的指令來調整緩衝行為。大多數時候不必擔心太多,但它對於調整一些值可能是有用的。可能最有用的調整是proxy_buffers和proxy_buffer_size指令,比如:
proxy_busy_buffers_size 8k;
proxy_max_temp_file_size 2048m;
proxy_temp_file_write_size 32k;
proxy_pass http://www.wang.com;

-----------------------------配置Nginx代理服務快取來減少響應時間-----------------------------
儘管緩衝可以幫助釋放後端伺服器以處理更多的請求,Nginx還提供了一種方法來快取從後端伺服器的內容,對於許多請求無需連線到上游。
配置代理快取,要設定快取用於代理內容,可以使用proxy_cache_path指令。這將建立區域儲存來自被代理伺服器返回的資料。該proxy_cache_path指令必須在HTTP上下文部分進行設定。

比如下面的例子中,我們將配置一些相關的指令來建立快取系統。
# http context
proxy_cache_path /var/nginx/cache levels=1:2 keys_zone=backcache:8m max_size=50m;
proxy_cache_key "$scheme$request_method$host$request_uri$is_args$args";
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;

用proxy_cache_path指令,首先應該已經定義在檔案系統中希望儲存快取的目錄。在這個例子中,選擇在/var/nginx/cache目錄。如果該目錄不存在,可以用正確的許可權和所有權建立它:
mkdir -p /var/nginx/cache
chown www /var/nginx/cache
chmod 700 /var/nginx/cache

levels=引數指定快取將如何組織。 Nginx將通過雜湊鍵(下方配置)的值來建立一個快取鍵。選擇了上述的levels決定了單個字元目錄(這是雜湊值的最後一個字元)配有兩個字元的子目錄
(下兩個字元取自雜湊值的末尾)將被建立。你通常不必對這個細節關注,但它可以幫助Nginx快速找到相關的值。

keys_zone=引數定義快取區域的名字,我們稱之為backcache。這也是我們定義多少後設資料儲存的地方。在這個例子裡,儲存8MB的key。對於每兆位元組,Nginx可儲存8000左右的條目。
MAX_SIZE引數設定實際快取資料的最大尺寸。

使用上面的另一個指令是proxy_cache_key。這個設定將設定用於儲存快取值的鍵。此鍵用於檢查是否一個請求可以從快取記憶體提供服務。將它設定成方案(http或https),HTTP請求方法,
以及被請求的主機和URI的組合。

proxy_cache_valid指令可以被指定多次。它依賴於狀態程式碼值使我們能夠配置多長時間儲存。在我們的例子中,我們對於後端返回200和302儲存10分鐘,404響應的一分鐘過期。

現在,已經配置了快取區,但仍然需要告訴Nginx什麼時候使用快取。在代理到後端的location位置,我們可以配置使用這個快取:
# server context
location /proxy-me {
proxy_cache backcache;
proxy_cache_bypass $http_cache_control;
add_header X-Proxy-Cache $upstream_cache_status;
proxy_pass http://backend;
}

使用proxy_cache指令,就可以指定該backcache快取區被用於這個位置。 Nginx會在這裡檢查傳遞給後端有效的條目。
上述proxy_cache_bypass指令被設定為$ http_cache_control變數。這將包含一個指示器,用以指示該客戶端是否被明確地請求一個最新的,非快取版本。設定此指令允許Nginx正確處理
這些型別的客戶端請求。無需進行進一步的配置。

此外還增加了被稱為X-Proxy-Cache的額外頭,設定這個頭部為$upstream_cache_status變數的值。這個設定頭可以看到,如果請求導致快取記憶體命中,快取記憶體未命中,或者快取記憶體被
明確旁路。這是對於除錯特別有價值,也對客戶端是有用的資訊。

-------------------------關於快取結果的注意事項-------------------------
快取記憶體能夠極大地提高代理伺服器的效能。不過,也需要明確的考慮配置快取時候,要記住。
-> 首先,任何使用者相關的資料不應被快取記憶體。這可能導致一個使用者的資料被呈現給其他使用者。如果你的網站是完全靜態的,這可能不是一個問題。
如果網站有一些動態元素,將不得不考慮到這一點。如何處理要看是什麼應用程式或伺服器處理的後端處理。
對於私人的內容,應該設定Cache-Control頭為“no-cache”,“no-sotre”,或者“private”依賴於資料的性質:

no-cache:
請求: 告知快取者,必須原原本本的轉發原始請求,並告知任何快取者,需要去轉發請求,並驗證快取(如果有的話).對應名詞:端對端過載.    
響應: 允許快取者快取副本.那麼其實際價值是,總是強制快取者,校驗快取的新鮮度.一旦確認新鮮,則可以使用快取副本作為響應。no-cache,還可以指定某個包含欄位,
      比如一個典型應用,no-cache=Set-Cookie. 這樣做的結果,就是告知快取者,對於Set-Cookie欄位,你不要使用快取內容.而是使用新滴.其他內容則可以使用快取

no-store:表示在任何時候收到的資料不被快取。這對於私人資料是最安全,因為它意味著,該資料必須從伺服器每次進行檢索。
private:這表明共享的快取空間不能快取此資料。這可以用於指示使用者的瀏覽器快取記憶體資料,但代理伺服器不應當考慮隨後的請求資料有效。
public:這表明該響應是可在連線的任何點被快取記憶體的公共資料。

一個相關的可以控制此行為報頭是max-age頭,其指示,任何資源應該快取的秒數。
根據內容的敏感性,正確設定這些頭,會幫助你利用快取優勢,同時保持你的私人資料安全,並使您的動態資料最新。
如果後端也使用Nginx,你可以設定使用過期指令,設定max-age來實現Cache-Control:
location / {
expires 60m;
}

location /check-me {
expires -1;
}

在上面的例子中,第一個塊允許快取一個小時的內容。第二塊設定Cache-Control頭為“無快取”。要設定其他值,可以使用add_header指令,就像這樣:
location /private {
expires -1;
add_header Cache-Control "no-store";
}

-------------------------------------------------本機快取配置(80埠轉8080,不使用ngx_cache_purge模組)-----------------------------------------------

1)nginx正常編譯安裝(不需要ngx_cache_purge模組)。下載地址:http://nginx.org/en/download.html
[root@test ~]# yum install -y pcre pcre-devel openssl openssl-devel gcc
[root@test ~]# cd /data/software
[root@test software]# tar zxvf nginx-1.10.3.tar.gz
[root@test software]# cd nginx-1.10.3
[root@test nginx-1.10.3]# ./configure --prefix=/data/nginx --with-http_ssl_module --with-http_flv_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre
[root@test nginx-1.10.3]# make && make install
[root@test nginx-1.10.3]# /data/nginx/sbin/nginx

[root@test nginx-1.10.3]# ls /data/nginx/
client_body_temp conf fastcgi_temp html logs proxy_temp sbin scgi_temp uwsgi_temp

2) 進行cache快取配置。快取檔案在tomcat程式裡,即配置80代理到8080(tomcat程式埠)

[root@test nginx-1.10.3]# cat /data/nginx/conf/nginx.conf
#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

     upstream backend_servers {  
              server 127.00.0.1:8080;    
     }
  
    proxy_cache_path /data/nginx/proxy_cache levels=1:2 keys_zone=mycache:500m inactive=1h max_size=30g;

    server {
        listen       80;
        server_name  localhost 192.168.1.19;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location = /apollo/1.html {
             root /usr/local/nginx/html;
        }

        location / {
           # root   html;
           # index  index.html index.htm;
            proxy_pass http://backend_servers;  
            
            proxy_redirect off;  
            proxy_set_header Host $host;  
            proxy_set_header X-Real-IP $remote_addr;  
            proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;  
           
            proxy_cache mycache; 
            proxy_cache_valid  200 304  12h; 
            proxy_cache_valid any 1m;
                        client_max_body_size  100m;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

}

[root@test nginx-1.10.3]# mkdir /data/nginx/proxy_cache                  //建立上面配置中的cache目錄,注意:這裡只是配置了一個cache路徑,temp路徑採用預設的。 
[root@test nginx-1.10.3]# /data/nginx/sbin/nginx -t
nginx: the configuration file /data/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /data/nginx/conf/nginx.conf test is successful
[root@test nginx-1.10.3]# /data/nginx/sbin/nginx -s reload

------快取效果測試--------:

有上面可以看出,80代理到8080的配置已經生效!下面看下快取檔案是否生成:

[root@test nginx-1.10.3]# ll /data/nginx/
total 40
drwx------ 2 nginx root 4096 Sep 1 17:54 client_body_temp
drwxr-xr-x 2 root root 4096 Sep 1 20:22 conf
drwx------ 2 nginx root 4096 Sep 1 17:54 fastcgi_temp
drwxr-xr-x 2 root root 4096 Sep 1 17:54 html
drwxr-xr-x 2 root root 4096 Sep 1 18:30 logs
drwxr-xr-x 6 nginx root 4096 Sep 1 20:22 proxy_cache
drwx------ 10 nginx root 4096 Sep 1 20:24 proxy_temp
drwxr-xr-x 2 root root 4096 Sep 1 18:01 sbin
drwx------ 2 nginx root 4096 Sep 1 17:54 scgi_temp
drwx------ 2 nginx root 4096 Sep 1 17:54 uwsgi_temp
[root@test nginx-1.10.3]# ll /data/nginx/proxy_cache/
total 16
drwx------ 3 nginx nginx 4096 Sep 1 20:22 2
drwx------ 4 nginx nginx 4096 Sep 1 20:22 7
drwx------ 3 nginx nginx 4096 Sep 1 19:48 8
drwx------ 3 nginx nginx 4096 Sep 1 19:48 f
[root@test nginx-1.10.3]# ll /data/nginx/proxy_temp/            #預設的temp目錄
total 32
drwx------ 3 nginx nginx 4096 Sep 1 19:48 1
drwx------ 3 nginx nginx 4096 Sep 1 19:48 2
drwx------ 3 nginx nginx 4096 Sep 1 19:48 3
drwx------ 3 nginx nginx 4096 Sep 1 20:22 4
drwx------ 3 nginx nginx 4096 Sep 1 20:22 5
drwx------ 3 nginx nginx 4096 Sep 1 20:22 6
drwx------ 3 nginx nginx 4096 Sep 1 20:23 7
drwx------ 3 nginx nginx 4096 Sep 1 20:24 8

 可以看出,快取檔案已經生成!要是清理快取的話,就清空上面兩個目錄即可!

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

再看下結合purge模組的快取配置:
[root@storage01 ~]# cat /data/nginx/conf/nginx.conf
#user  nobody;
worker_processes  4;
   
events {
    worker_connections  65535;
}
   
http {
    include       mime.types;
    default_type  application/octet-stream;
    charset utf-8;
  
    log_format  main  '$http_x_forwarded_for $remote_addr $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_cookie" $host $request_time';
    sendfile       on;
    tcp_nopush     on;
    tcp_nodelay    on;
    keepalive_timeout  65;
  
    proxy_temp_path /data/nginx/proxy_temp;
    proxy_cache_path /data/nginx/proxy_cache levels=1:2 keys_zone=mycache:500m inactive=1d max_size=30g;
      
    client_header_timeout 600s;
    client_body_timeout 600s;
   
    client_max_body_size 50m;            
    client_body_buffer_size 256k;          
   
    gzip  on;
    gzip_min_length  1k;
    gzip_buffers     4 16k;
    gzip_http_version 1.1;
    gzip_comp_level 9;
    gzip_types       text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php;
    gzip_vary on;
   
    include vhosts/*.conf;
}


[root@storage01 ~]# mkdir proxy_cache
[root@storage01 ~]# mkdir proxy_temp
[root@storage01 ~]# chown -R nginx.nginx proxy_cache
[root@storage01 ~]# chown -R nginx.nginx proxy_temp
[root@storage01 ~]# chmod -R 777 proxy_cache
[root@storage01 ~]# chmod -R 777 proxy_temp


[root@storage01 ~]# cat /data/nginx/conf/vhosts/cache.conf 
upstream backend_servers {  
              server 127.0.0.1:8080;    
     }

server {
        listen       80;
        server_name  localhost 192.168.1.25;

        access_log  /data/nginx/logs/80-access.log main;
        error_log  /data/nginx/logs/80-error.log;


        location / {
           # root   html;
           # index  index.html index.htm;
            proxy_pass http://backend_servers;  
            
            proxy_redirect off;  
            proxy_set_header Host $host;  
            proxy_set_header X-Real-IP $remote_addr;  
            proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;  
           
            proxy_cache mycache; 
            proxy_cache_valid  200 304  12h; 
            proxy_cache_valid any 1m;
            proxy_cache_key $host$uri$is_args$args;

        }

        #error_page  404              /404.html;
        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        location ~ /purge(/.*) {
           allow all ;
           proxy_cache_purge mycache $host$1$is_args$args ;
           error_page 405 =200 /purge$1;
        }
}


訪問http://192.168.1.25/storage/   反向代理到 http://192.168.1.25:8080/storage/

清理快取的正確方式:http://192.168.1.25/purge/storage/

相關文章