Nginx 內容快取及常見引數配置

he_xd發表於2019-05-15

原文連結:何曉東 部落格

使用場景:專案的頁面需要載入很多資料,也不是經常變化的,不涉及個性化定製,為每次請求去動態生成資料,效能比不上根據請求路由和引數快取一下結果,使用 Nginx 快取將大幅度提升請求速度。
基礎

只需要配置 proxy_cache_pathproxy_cache 就可以開啟內容快取,前者用來設定快取的路徑和配置,後者用來啟用快取。

http {
    ...
    proxy_cache_path /path/to/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;

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

對應引數說明:

1.用於快取的本地磁碟目錄是 /path/to/cache/

2.levels 在 /path/to/cache/ 設定了一個兩級層次結構的目錄。將大量的檔案放置在單個目錄中會導致檔案訪問緩慢,所以針對大多數部署,我們推薦使用兩級目錄層次結構。如果 levels 引數沒有配置,則 NGINX 會將所有的檔案放到同一個目錄中。

3.keys_zone 設定一個共享記憶體區,該記憶體區用於儲存快取鍵和後設資料,有些類似計時器的用途。將鍵的拷貝放入記憶體可以使 NGINX 在不檢索磁碟的情況下快速決定一個請求是 HIT 還是 MISS,這樣大大提高了檢索速度。一個 1MB 的記憶體空間可以儲存大約 8000 個 key,那麼上面配置的 10MB 記憶體空間可以儲存差不多 80000 個key。

4.max_size 設定了快取的上限(在上面的例子中是 10G)。這是一個可選項;如果不指定具體值,那就是允許快取不斷增長,佔用所有可用的磁碟空間。當快取達到這個上線,處理器便呼叫 cache manager 來移除最近最少被使用的檔案,這樣把快取的空間降低至這個限制之下。

5.inactive 指定了專案在不被訪問的情況下能夠在記憶體中保持的時間。在上面的例子中,如果一個檔案在 60 分鐘之內沒有被請求,則快取管理將會自動將其在記憶體中刪除,不管該檔案是否過期。該引數預設值為 10 分鐘(10m)。注意,非活動內容有別於過期內容。NGINX 不會自動刪除由快取控制頭部指定的過期內容(本例中Cache-Control:max-age=120)。過期內容只有在 inactive 指定時間內沒有被訪問的情況下才會被刪除。如果過期內容被訪問了,那麼 NGINX 就會將其從原伺服器上重新整理,並更新對應的 inactive 計時器。

6.NGINX 最初會將註定寫入快取的檔案先放入一個臨時儲存區域, use_temp_path=off 命令指示 NGINX 將在快取這些檔案時將它們寫入同一個目錄下。我們強烈建議你將引數設定為 off 來避免在檔案系統中不必要的資料拷貝。use_temp_path 在 NGINX1.7 版本和 NGINX Plus R6 中有所介紹。

最終,proxy_cache 命令啟動快取那些 URL 與 location 部分匹配的內容(本例中,為/)。你同樣可以將 proxy_cache 命令新增到 server 部分,這將會將快取應用到所有的那些 location 中未指定自己的 proxy_cache 命令的服務中。

Nginx 快取相關程式

快取中還涉及兩個額外的NGINX程式:

  • cache manager 週期性地啟動,檢查快取記憶體的狀態。如果快取記憶體大小超過 proxy_cache_path 中 max_size 引數設定的限制,則快取記憶體管理器將刪除最近訪問過的資料。在兩次快取管理器啟動的間隔,快取的資料量可能短暫超過配置的大小。
  • cache loader 只執行一次,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;
其他常用引數

配置示例:

proxy_cache_path /path/to/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;

server {
    ...
    location / {
        proxy_cache my_cache;
        # proxy_cache_key "$host$request_uri$cookie_user";
        proxy_cache_min_uses 3;
        proxy_cache_methods GET HEAD POST;
        proxy_cache_valid 200 302 10m;
        proxy_cache_valid 404      1m;
        # proxy_cache_valid any 5m;
        proxy_pass http://localhost:8000;
    }
}

對應引數說明:

proxy_cache_key 為更改計算金鑰時使用的請求特徵,指定快取的 key,這個不推薦,示例是使用域名,請求url,使用者 cookie 來當作 key,意味著一個頁面將為不同的使用者快取 n 次,絕大多數情況不需要這樣的操作。

proxy_cache_min_uses 為在快取響應之前必須使用相同金鑰的請求的最小次數。

proxy_cache_methods 為指定要被快取的請求方式的響應值,預設為 GET 和 HEAD,新增其他的需要一起列出來,如上示例所示。

proxy_cache_valid 為響應狀態碼的快取時間,示例可以為每個狀態碼快取指定時間,也可以使用 any 進行全部狀態碼的快取。

清除快取

需要提前加一個配置,用於標識使用 HTTP PURGE 方法的請求並刪除匹配的 URL 對應的快取。<br/>
1.在 http {} 上下文中建立新變數,例如 $purge_method, 他依賴於 $request_method 變數:

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

2.在 location {} 塊中,已經配置快取的前提下,引入 proxy_cache_purge 引數來指定清除快取請求的條件。例如在上一步指定的 $request_method

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

    location / {
        proxy_pass  https://localhost:8002;
        proxy_cache mycache;

        proxy_cache_purge $purge_method;
    }
}

配置完並使之生效之後,就可以傳送一條 purge 請求來讓快取失效了,例如:

curl -X PURGE -D – "https://www.example.com/*"

在該示例中,將清除具有公共 URL 部分(由星號萬用字元指定)的資源。但這些快取條目不會從快取中完全刪除:它們會保留在磁碟上,直到它們被視為不活動(由proxy_cache_path 中的 inactive引數決定)的時候才完全刪除,或快取清除器(由 proxy_cache_path 中的 purge 決定),或客戶端嘗試訪問它們的時候。

參考連結:

  1. Nginx 快取使用官方指南
  2. Nginx 內容快取文件

更多文章會更新在個人部落格上。

相關文章