Nginx 代理快取

13sai發表於2019-11-20

Nginx的快取可以簡單分成web快取和代理快取,本篇文章主要介紹代理快取。

相關文章:

web快取

Nginx提供了expires、etag、if-modified-since指令來實現瀏覽器快取控制。

這個配置比較簡單,一般可以快取一些js、css等靜態檔案。

對於這幾個不想做過多說明,大家可以看兩張圖,簡單理解下。

瀏覽器快取

Nginx 代理快取

代理快取

代理快取主要用到proxy模組中的proxy_cache。我們來看一個demo。

upstream 13sai{
    server 127.0.0.1:9501 weight=10;
}

#自定義快取目錄,快取檔案大小
proxy_cache_path  /usr/local/etc/nginx/cache  levels=1:2  keys_zone=sai_cache:10m  max_size=200m inactive=10m  use_temp_path=off;

server {
    listen       80;
    server_name  nginx-t.com;

    location / {
        proxy_next_upstream error http_503;
        proxy_pass http://13sai;

        #啟用快取sai_cache
        proxy_cache sai_cache; 

        #定義如何生成快取的鍵
        proxy_cache_key $scheme$proxy_host$uri$is_args$args;

        #針對多種請求方法快取,預設GET HEAD
        proxy_cache_methods GET HEAD POST; 

        #為不同的響應狀態碼設定不同的快取時間。
        proxy_cache_valid 200 302 10m;
        proxy_cache_valid 404      1m;

        #設定響應被快取的最小請求次數,最少2次才會快取
        proxy_cache_min_uses 1;

        #開啟此功能時,對於相同的請求,同時只允許一個請求發往後端
        proxy_cache_lock on; 

        #為proxy_cache_lock指令設定鎖的超時5s
        proxy_cache_lock_timeout 5s;

        #忽略伺服器不快取的要求
        proxy_ignore_headers Cache-Control; 
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
    }

}

測試效果

// server1.php
<?php
$http = new Swoole\Http\Server("127.0.0.1", 9501);
$http->on('request', function ($request, $response) {
    echo "no cache".PHP_EOL;
    $response->end("<h1>9501</h1>");
});
$http->start();

php server1.php #檢視控制檯輸出

傳送get和post請求

ab -n10 -c10 http://nginx-t.com/v\=get

ab -p 'data.json' -n10 -c10 http://nginx-t.com/v\=post

重複提交幾次put請求

curl -X PUT http://nginx-t.com/v\=put

下面是我的測試結果截圖(為了方便檢視,我在get和post請求之前敲了幾個空行)

Nginx 快取

下面說明幾個引數:

proxy_cache_path

語法: proxy_cache_path path [levels=levels] keys_zone=name:size [inactive=time] [max_size=size] [loader_files=number] [loader_sleep=time] [loader_threshold=time];
預設值:    —
上下文:    http
  • path:快取資料是儲存在檔案中的,快取的鍵和檔名都是在代理URL上執行MD5的結果。
  • levels:定義了快取的層次結構
    #當levels=1:2時,表示是兩級目錄,1和2表示用1位和2位16進位制來命名目錄名稱。在此例中,第一級目錄用1位16進位制命名,如b;第二級目錄用2位16進位制命名,如2c。所以此例中一級目錄有16個,二級目錄有16*16=256個:
    cache/b/2c/c75ad5e343f042f52e875343425e51b
  • key_zone:在共享記憶體中設定一塊儲存區域來存放快取的key和metadata(類似使用次數),這樣nginx可以快速判斷一個request是否命中或者未命中緩 存,1m可以儲存8000個key,10m可以儲存80000個key。
  • max_size:最大cache空間,如果不指定,會使用掉所有disk space,如果超過max_size引數設定的最大值,使用LRU演算法移除快取資料
  • inactive:未被訪問檔案在快取中保留時間,預設是10分鐘。指定時間內未被訪問的快取檔案將被刪除。
  • loader_files:每次最多載入的數量
  • loader_sleeps:每次載入的延時
  • loader_threshold:指定每次載入執行的時間

proxy_cache_lock

開啟此功能時,對於相同的請求,同時只允許一個請求發往後端,並根據proxy_cache_key指令的設定在快取中植入一個新條目。其他請求相同條目的請求將一直等待,直到快取中出現相應的內容,或者鎖在proxy_cache_lock_timeout指令設定的超時後被釋放。

proxy_cache_valid

如果僅僅指定了time,

proxy_cache_valid 5m;

那麼只有狀態碼為200、300和302的響應會被快取。

如果使用了any引數,那麼就可以快取任何響應:

proxy_cache_valid any 1m;

proxy_ignore_headers

語法: proxy_ignore_headers field ...;
預設值:    —
上下文:    http, server, location

不處理後端伺服器返回的指定響應頭。下面的響應頭可以被設定: “X-Accel-Redirect”,“X-Accel-Expires”,“X-Accel-Limit-Rate” ,“X-Accel-Buffering” , “X-Accel-Charset”,“Expires”,“Cache-Control”,和“Set-Cookie” 。

此引數不建議設定,原則上這些快取應當後端程式碼處理。

proxy_cache_use_stale

語法: proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504 | http_404 | off ...;
預設值:    
proxy_cache_use_stale off;
上下文:    http, server, location

如果後端伺服器出現狀況,nginx是可以使用過期的響應快取的。這條指令就是定義何種條件下允許開啟此機制。這條指令的引數與proxy_next_upstream指令的引數相同。

proxy_cache_bypass與proxy_no_cache

語法: proxy_cache_bypass string ...;
預設值:    —
上下文:    http, server, location

定義nginx不從快取取響應的條件。如果至少一個字串條件非空而且非“0”,nginx就不會從快取中去取響應:

proxy_cache_bypass $cookie_nocache $arg_nocache$arg_comment;
proxy_cache_bypass $http_pragma    $http_authorization;

本指令可和與proxy_no_cache一起使用。

語法: proxy_no_cache string ...;
預設值:    —
上下文:    http, server, location

定義nginx不將響應寫入快取的條件。如果至少一個字串條件非空而且非“0”,nginx就不將響應存入快取:

proxy_no_cache $cookie_nocache $arg_nocache$arg_comment;
proxy_no_cache $http_pragma    $http_authorization;

proxy_cache_methods

該指令用於設定快取哪些HTTP方法,預設快取HTTP GET/HEAD方法,不快取HTTP POST 方法。

有了代理快取,那麼清除快取如何操作呢?

清除快取

  1. 刪除快取目錄的檔案
  2. 使用ngx_cache_purge模組,可檢視這篇文章Nginx快取配置及nginx ngx_cache_purge模組的使用

推薦第二種方法。

分享開發知識,歡迎交流。

相關文章