Nginx內容快取


本節介紹如何啟用和組態從代理伺服器接收的響應的快取。主要涉及以下內容 -

  • 快取介紹
  • 啟用響應快取
  • 涉及快取的NGINX進程
  • 指定要快取的請求
  • 限制或繞過快取
  • 從快取中清除內容
    • 組態快取清除
    • 傳送清除命令
    • 限制存取清除命令
    • 從快取中完全刪除檔案
    • 快取清除組態範例
  • 位元組快取
  • 組合組態範例

1. 介紹

當啟用快取時,NGINX將響應儲存在磁碟快取中,並使用它們來響應用戶端,而不必每次都為同一內容代理請求。

2. 啟用響應快取

要啟用快取,請在頂層的http上下文中包含proxy_cache_path指令。 強制的第一個引數是快取內容的本地檔案系統路徑,強制keys_zone引數定義用於儲存有關快取專案的後設資料的共用記憶體區域的名稱和大小:

http {
    ...
    proxy_cache_path /data/nginx/cache keys_zone=one:10m;
}

然後在要快取伺服器響應的上下文(協定型別,虛擬伺服器或位置)中包含proxy_cache指令,將由keys_zone引數定義的區域名稱指定為proxy_cache_path指令(在本例中為一):

http {
    ...
    proxy_cache_path /data/nginx/cache keys_zone=one:10m;

    server {
        proxy_cache one;
        location / {
            proxy_pass http://localhost:8000;
        }
    }
}

請注意,由keys_zone引數定義的大小不會限制快取的響應資料的總量。 快取響應本身儲存在檔案系統上的特定檔案中的後設資料副本。 要限制快取的響應資料量,請將max_size引數包含到proxy_cache_path指令中(但請注意,快取資料的數量可能會臨時超出此限制,如以下部分所述。)

3. 涉及快取的NGINX進程

快取中還有兩個額外的NGINX進程:

  • 快取管理器週期性地被啟用以檢查快取的狀態。 如果快取大小超過了由max_cize_path指令設定的max_size引數,快取管理器將刪除最近存取的資料。如前所述,快取記憶體管理器啟用之間的快取資料量可以臨時超過限制。

  • NGINX啟動後,快取載入程式只執行一次。 它將有關以前快取的資料的後設資料載入到共用記憶體區域。一次載入整個快取可能會在啟動後的最初幾分鐘內消耗足夠的資源來減慢NGINX的效能。 為了避免這種情況,請通過將以下引數包含到proxy_cache_path偽指令來組態快取的疊代載入:

    • loader_threshold - 疊代的持續時間,以毫秒為單位(預設為200)
    • loader_files - 在一次疊代期間載入的最大專案數(預設為100)
    • loader_sleeps - 疊代之間的延遲(以毫秒為單位)(預設為50)

在以下範例中,迭代持續300毫秒或直到載入了200個專案:

proxy_cache_path /data/nginx/cache keys_zone=one:10m loader_threshold=300 loader_files=200;

4. 指定要快取的請求

預設情況下,NGINX首次從代理伺服器接收到這樣的響應後,快取對HTTP GETHEAD方法的請求的所有響應。 作為請求的金鑰(識別符號),NGINX使用請求字串。 如果請求具有與快取響應相同的金鑰,則NGINX將快取的響應傳送給用戶端。 您可以在http, server, 或 location上下文中包含各種指令,以控制哪些響應被快取。

要更改在計算金鑰時使用的請求字元,請包括proxy_cache_key偽指令:

proxy_cache_key "$host$request_uri$cookie_user";

要定義在快取響應之前必須進行具有相同金鑰的請求的最小次數,請包括proxy_cache_min_uses指令:

proxy_cache_min_uses 5;

要使用除GET和HEAD之外的方法來快取對請求的響應,請將它們與GET和HEAD一起列為proxy_cache_methods偽指令的引數:

proxy_cache_methods GET HEAD POST;

5. 限制或繞過快取

預設情況下,響應將無限期地保留在快取中。 只有快取超過最大組態大小,然後按照最後一次請求的時間長度,它們才被刪除。 您可以通過在http, server, 或 location上下文中包含指令來設定快取響應被認為有效的時間長度,甚至是否使用它們。

要限制快取響應與特定狀態程式碼被認為有效的時間,請包括proxy_cache_valid指令:

proxy_cache_valid 200 302 10m;
proxy_cache_valid 404      1m;

在此範例中,使用程式碼200302的響應有效時間為10分鐘,並且程式碼404的響應有效1分鐘。 要定義具有所有狀態程式碼的響應的有效時間,請指定any作為第一個引數:

proxy_cache_valid any 5m;

要定義NGINX不會向用戶端傳送快取響應的條件,請包括proxy_cache_bypass指令。 每個引數定義一個條件並由多個變數組成。 如果至少有一個引數不為空,並且不等於「0」(零),則NGINX不會在快取中查詢響應,而是將請求立即轉發到後端伺服器。

proxy_cache_bypass $cookie_nocache $arg_nocache$arg_comment;

要定義NGINX根本不快取響應的條件,請包括proxy_no_cache指令,以與proxy_cache_bypass偽指令相同的方式定義引數。

proxy_no_cache $http_pragma $http_authorization;

6. 從快取中清除內容

NGINX可以從快取中刪除過期的快取檔案。刪除過期的快取內容以防止同時提供舊版本和新版本的網頁。 在接收到包含自定義HTTP頭或「PURGE」 HTTP方法的特殊「purge」請求時,快取被清除。

6.1 組態快取清除

我們設定一個組態來標識使用「PURGE」 HTTP方法的請求並刪除匹配的URL。

  1. http塊層級上,建立一個新變數,例如:$purge_method,這將取決於$request_method變數:
http {
    ...
    map $request_method $purge_method {
        PURGE 1;
        default 0;
    }
}
  1. location中組態快取記憶體,包括指定快取清除請求的條件的proxy_cache_purge指令。 在我們的例子中,它是在上一步組態的$purge_method

    server {
     listen      80;
     server_name www.example.com;
    
     location / {
         proxy_pass  http://localhost:8002;
         proxy_cache mycache;
    
         proxy_cache_purge $purge_method;
     }
    }
    

    6.3 傳送清除命令

組態proxy_cache_purge指令後,您需要傳送一個特殊的快取清除請求來清除快取。 您可以使用一系列工具發出清除請求,例如curl命令:

$ curl -X PURGE -D – "http://www.example.com/*"
HTTP/1.1 204 No Content
Server: nginx/1.5.7
Date: Sat, 01 Dec 2015 16:33:04 GMT
Connection: keep-alive

在該範例中,具有公共URL部分(由星號萬用字元指定)的資源將被刪除。 但是,這些快取記憶體條目將不會從快取中完全刪除:它們將保留在磁碟上,直到它們被刪除為非活動狀態(proxy_cache_path的非活動引數),或由快取清除程式進程處理,或用戶端嘗試存取它們 。

6.4 限制存取清除命令

建議您組態允許傳送快取清除請求的有限數量的IP地址:

geo $purge_allowed {
   default         0;  # deny from other
   10.0.0.1        1;  # allow from localhost
   192.168.0.0/24  1;  # allow from 10.0.0.0/24
}

map $request_method $purge_method {
   PURGE   $purge_allowed;
   default 0;
}

在這個例子中,NGINX檢查請求中是否使用「PURGE」方法,如果是,分析用戶端IP地址。 如果IP地址被列入白名單,那麼$purge_method設定為$purge_allowed:「1」允許清除,「0」表示清除。

6.5 從快取中完全刪除檔案

要完全刪除與星號相匹配的快取檔案,您將需要啟用一個特殊的快取清除程式,該過程將永久地遍歷所有快取條目,並刪除與萬用字元相匹配的條目。 在http塊級別上,將purger引數新增到proxy_cache_path指令中:

proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=mycache:10m purger=on;

6.6 快取清除組態範例

http {
    ...
    proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=mycache:10m purger=on;

    map $request_method $purge_method {
        PURGE 1;
        default 0;
    }

    server {
        listen      80;
        server_name www.example.com;

        location / {
            proxy_pass        http://localhost:8002;
            proxy_cache       mycache;
            proxy_cache_purge $purge_method;
        }
    }

    geo $purge_allowed {
       default         0;
       10.0.0.1        1;
       192.168.0.0/24  1;
    }

    map $request_method $purge_method {
       PURGE   $purge_allowed;
       default 0;
    }
}

7. 位元組快取

有時,初始快取填充操作可能需要一些時間,特別是對於大檔案。 當第一個請求開始下載視訊檔案的一部分時,下一個請求將不得不等待整個檔案被下載並放入快取記憶體。

NGINX使快取這樣的範圍請求成為可能,並逐漸用快取片模組填充快取記憶體。 該檔案分為較小的「切片」。 每個範圍請求選擇將覆蓋所請求範圍的特定切片,並且如果此範圍仍未快取,請將其放入快取中。 對這些切片的所有其他請求將從快取中獲取響應。

要啟用位元組範圍快取:

  1. 確保您的NGINX是使用slice模組編譯的。

  2. 使用slice指令指定切片的大小:

    location / {
     slice  1m;
    }
    

    slice的大小應適當調整,使切片快速下載。 在處理請求時,太小的大小可能會導致記憶體使用量過多和大量開啟的檔案描述符,太大的值可能會導致延遲。

  3. $slice_range變數包含到快取鍵中:

proxy_cache_key $uri$is_args$args$slice_range;
  1. 啟用使用206狀態程式碼快取響應:

    proxy_cache_valid 200 206 1h;
    
  2. 通過在Range頭欄位中傳遞$slice_range變數來將傳遞範圍請求設定為代理伺服器:

proxy_set_header  Range $slice_range;

位元組範圍快取範例:

location / {
    slice             1m;
    proxy_cache       cache;
    proxy_cache_key   $uri$is_args$args$slice_range;
    proxy_set_header  Range $slice_range;
    proxy_cache_valid 200 206 1h;
    proxy_pass        http://localhost:8000;
}

請注意,如果切片(slice)快取開啟,則不應更改初始檔案。

8. 組合組態範例

以下範例組態組合了上述某些快取選項。

http {
    ...
    proxy_cache_path /data/nginx/cache keys_zone=one:10m loader_threshold=300 
                     loader_files=200 max_size=200m;

    server {
        listen 8080;
        proxy_cache one;

        location / {
            proxy_pass http://backend1;
        }

        location /some/path {
            proxy_pass http://backend2;
            proxy_cache_valid any 1m;
            proxy_cache_min_uses 3;
            proxy_cache_bypass $cookie_nocache $arg_nocache$arg_comment;
        }
    }
}

在這個例子中,兩個位置使用相同的快取,但是以不同的方式。

由於backend1伺服器的響應很少更改,因此不包括快取控制指令。 首次請求響應快取,並無限期保持有效。

相比之下,對backend2服務的請求的響應頻繁變化,因此它們被認為只有1分鐘有效,並且在相同請求3次之前不被快取。 此外,如果請求符合proxy_cache_bypass指令定義的條件,則NGINX會立即將請求傳遞給backend2,而不在快取中查詢。