如何在NGINX中緩存內容

NGINX 是一個整合的開源、高性能網頁伺服器,可加快內容和應用程式傳遞速度,增強安全性,並提高可擴展性。 Nginx 的其中一個最常見用途是 內容快取,這是提升網站性能的最有效方式。

閱讀更多Linux 的 10 大頂尖開源快取工具

您可以使用 NGINX 來加速本地原始伺服器,通過配置它來快取上游伺服器的回應,並為內容傳遞網路(CDNs)創建邊緣伺服器。 NGINX 驅動一些最大的 CDN。

當配置為快取時,NGINX 將:

  • 快取靜態和動態內容。
  • 通過微快取提高動態內容性能。
  • 在後台提供過時內容的服務,以實現更好的性能重新驗證。
  • 覆蓋或設置快取控制標頭,等等。

在本文中,您將學習如何在 Linux 中配置 NGINX 作為 內容快取,使您的網頁伺服器盡可能高效運行。

先決條件:

如果尚未安裝 Nginx,您應在 Linux 伺服器上安裝 NGINX,如果尚未安裝,請按照以下指南安裝 Nginx:

在Nginx上緩存靜態內容

靜態內容是網站上保持不變(不變)的內容,跨頁面保持一致。靜態內容的示例包括圖像、視頻、文檔;CSS文件和JavaScript文件等文件。

如果您的網站使用了大量靜態內容,則可以通過啟用客戶端緩存來優化其性能,其中瀏覽器存儲靜態內容的副本以加快訪問速度。

以下示例配置是一個不錯的選擇,只需將www.example.com替換為您的網站名稱的URL,並根據需要對其他路徑進行修改。

server {
    # substitute your web server's URL for www.example.com
    server_name www.example.com;
    root /var/www/example.com/htdocs;
    index index.php;

    access_log /var/log/nginx/example.com.access.log;
    error_log /var/log/nginx/example.com.error.log;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ .php$ {
        try_files $uri =404;
        include fastcgi_params;
        # substitute the socket, or address and port, of your WordPress server
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        #fastcgi_pass 127.0.0.1:9000;
 	}   

    location ~* .(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg
                  |jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid
                  |midi|wav|bmp|rtf)$ {
        expires max;
        log_not_found off;
        access_log off;
    }
}

在Nginx上緩存動態內容

NGINX使用位於本地文件系統某處的持久性基於磁盤的緩存。因此,首先創建用於存儲緩存內容的本地磁盤目錄。
# mkdir -p /var/cache/nginx

接下來,在緩存目錄上設置適當的所有權。它應該由NGINX用戶(nginx)和組(nginx)擁有,如下所示。

# chown nginx:nginx /var/cache/nginx

現在繼續查看如何在下面的部分啟用Nginx上的動態內容。

在NGINX中啟用FastCGI緩存

FastCGI(或FCGI)是一種廣泛用於將互動應用程式(如PHP)與網頁伺服器(如NGINX)進行接口的協議。它是CGI通用閘道介面)的擴展。

FCGI的主要優勢在於它可以在單個進程中管理多個CGI請求。如果沒有它,網頁伺服器必須為每個客戶端對服務的請求打開一個新進程(必須受控制,處理請求,然後關閉)。

為了在LEMP堆棧部署中處理PHP腳本,NGINX使用FPMFastCGI進程管理器)或PHP-FPM,這是一個流行的替代PHP FastCGI實現。一旦PHP-FPM進程運行,NGINX被配置為代理請求以進行處理。因此,NGINX也可以被配置為緩存來自PHP-FPM後端應用伺服器的響應。

NGINX下,FastCGI內容緩存是通過一個名為fastcgi_cache_path的指令在頂層http{}上下文中聲明的,在NGINX配置結構中。您還可以添加fastcgi_cache_key,它定義了用於緩存的鍵(請求標識符)。

除了在http{}上下文中添加add_header X-Cache-Status指令以读取上游缓存状态外,这对于调试很有用。

假设您网站的服务器块配置文件位于/etc/nginx/conf.d/testapp.conf/etc/nginx/sites-available/testapp.conf(在Ubuntu及其衍生产品下),打开编辑文件并在文件顶部添加以下行。

fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=CACHEZONE:10m; inactive=60m max_size=40m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
add_header X-Cache $upstream_cache_status;
Enable FastCGI Cache in NGINX

fastcgi_cache_path指令指定以下参数的数量:

  • /var/cache/nginx – 缓存的本地磁盘目录路径。
  • levels – 定义缓存的层次结构,它在/var/cache/nginx下设置了一个两级目录结构。
  • keys_zone (name:size) – 启用共享内存区域的创建,其中存储所有活动密钥和数据(元数据)的信息。请注意,将密钥存储在内存中可以加快检查过程,使NGINX更容易确定其是MISS还是HIT,而无需在磁盘上检查状态。
  • inactive – 指定在指定时间内未访问的缓存数据将被删除的时间量,而不考虑其新鲜度。在我们的示例配置中,60m的值意味着在60分钟后未访问的文件将从缓存中删除。
  • max_size – 指定緩存的最大大小。這裡還有更多您可以使用的參數(閱讀 NGINX 文件以獲取更多信息)。

指令中的變數在 fastcgi_cache_key 指令中描述如下。

NGINX 在計算請求的鍵(標識符)時使用它們。重要的是,要將緩存的響應發送給客戶端,請求必須與緩存的響應具有相同的鍵。

  • $scheme – 請求方案,HTTP 或 HTTPS。
  • $request_method – 請求方法,通常是“GET”或“POST”。
  • $host – 這可以是請求行中的主機名稱,也可以是“Host”請求標頭字段中的主機名稱,或者是與請求匹配的服務器名稱,按優先順序。
  • $request_uri – 表示完整的原始請求 URI(帶參數)。

此外,$upstream_cache_status 變量在 add_header X-Cache-Status 指令中為 NGINX 响應的每個請求計算,無論它是一個 MISS(在緩存中未找到響應,從應用程序服務器獲得)還是一個 HIT(從緩存中提供的響應)或任何其他支持的值。

接下來,在將 PHP 請求傳遞給 PHP-FPMlocation 指令中,使用 fastcgi_cache 指令來激活您剛剛定義的緩存。

還可以使用 fastcgi_cache_valid 指令為不同的響應設置緩存時間,如所示。

fastcgi_cache CACHEZONE;
fastcgi_cache_valid  60m;
Define Caching Zone and Time

若僅指定快取時間,如我們的情況,則僅會快取 200301302 的響應。但您也可以明確指定響應,或使用任何響應代碼:

fastcgi_cache CACHEZONE;
fastcgi_cache_valid 200  301 203 60m;
fastcgi_cache_valid 404 10m;
OR
fastcgi_cache CACHEZONE;
fastcgi_cache_valid  any 10m;

在 Nginx 上微調 FastCGI 快取性能

要設置相同鍵的請求必須進行的最小次數,然後才能快取響應,請在 http{}server{}location{} 上下文中包含 fastcgi_cache_min_uses 指令。

fastcgi_cache_min_uses  3
Set Minimum Cache Usage

要使用帶有“If-Modified-Since”和“If-None-Match”標頭字段的條件請求來重新驗證過期快取項目,請在 http{}server{}location{} 上下文中添加 fastcgi_cache_revalidate 指令。

fastcgi_cache_revalidate on;
Set Cache Re-validation

您還可以指示 NGINX 在原始伺服器或 FCGI 伺服器故障時提供快取內容,使用 proxy_cache_use_stale 指令,在位置指令中。

此示例配置意味著當 NGINX 收到來自上游伺服器的錯誤、超時和指定的任何錯誤之一,並且在快取內容中有所請求的文件的過期版本時,它會提供過期的文件。

proxy_cache_use_stale error timeout http_500;
Enable Serving of Stale Data

另一個有用的指令來微調 FCGI 緩存性能是 fastcgi_cache_background_update,它與 proxy_cache_use_stale 指令配合使用。當設置為 on 時,它指示 NGINX 在客戶端請求已過期或正在從上游服務器更新的文件時提供陳舊的內容。

fastcgi_cache_background_update on;
Enable Cache Background Update

fastcgi_cache_lock 也很有用,用於緩存性能微調,當多個客戶端請求相同的內容並且該內容不在緩存中時,NGINX 只會將第一個請求轉發給上游服務器,緩存響應然後從緩存中為其他客戶端請求提供服務。

fastcgi_cache_lock on;
Enable Cache Lock

NGINX 配置文件中進行所有上述更改後,保存並關閉它。然後檢查配置結構是否存在任何語法錯誤,然後重新啟動 NGINX 服務。

# nginx -t
# systemctl restart nginx
Check and Start Nginx Service

接下來,測試緩存是否正常運作,嘗試使用以下 curl 命令 訪問您的 Web 應用程序或站點(第一次應顯示 MISS,但後續請求應該顯示 HIT,如屏幕截圖所示)。

# curl -I http://testapp.tecmint.com
Test FastCGI Cache

這是另一個屏幕截圖顯示 NGINX 提供陳舊數據。

Test Nginx Serving Stale Data

添加例外以繞過緩存

可以設置條件,使 NGINX 在使用 fastcgi_cache_bypass 指令時不向客戶端發送緩存的響應。要指示 NGINX 完全不緩存上游服務器的響應,請使用 fastcgi_no_cache

例如,如果您希望 POST 請求和帶有查詢字符串的 URL 總是發送到 PHP。首先,聲明一個 if 語句來設置條件如下。

set $skip_cache 0; 
if ($request_method = POST) { 
	set $skip_cache 1; 
} 

然後在 location 指令中啟用上述例外情況,將 PHP 請求傳遞給 PHP-FPM,使用 fastcgi_cache_bypassfastcgi_no_cache 指令。

 
fastcgi_cache_bypass $skip_cache; 
fastcgi_no_cache $skip_cache;

您的網站可能有許多其他部分,您可能不希望啟用內容緩存。以下是一個用於改善 WordPress 網站性能的 NGINX 配置示例,提供在 nginx.com 博客上。

要使用它,請進行更改(例如域名、路徑、文件名等),以反映您環境中的實際情況。

fastcgi_cache_path /var/run/NGINX-cache levels=1:2 keys_zone=WORDPRESS:100m inactive=60m; 
fastcgi_cache_key "$scheme$request_method$host$request_uri"; 
server { 
	server_name example.com www.example.com; 
	root /var/www/example.com; 
	index index.php; 
	access_log /var/log/NGINX/example.com.access.log; 
	error_log /var/log/NGINX/example.com.error.log; 
	set $skip_cache 0; 
	# POST requests and URLs with a query string should always go to PHP 	
	if ($request_method = POST) { 
		set $skip_cache 1; 
	} 
	if ($query_string != "") {
		set $skip_cache 1; 
	} 
	# Don't cache URIs containing the following segments 
	if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php |sitemap(_index)?.xml") { 
		set $skip_cache 1; 
	} 
	# Don't use the cache for logged-in users or recent commenters 
	if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass |wordpress_no_cache|wordpress_logged_in") {
		set $skip_cache 1; 
	} 
	location / { 
		try_files $uri $uri/ /index.php?$args; 
	} 
	location ~ .php$ { 
		try_files $uri /index.php; 
		include fastcgi_params; 
		fastcgi_pass unix:/var/run/php5-fpm.sock; 
		fastcgi_cache_bypass $skip_cache; 
		fastcgi_no_cache $skip_cache; 
		fastcgi_cache WORDPRESS; 
		fastcgi_cache_valid 60m; 
	} 
	location ~ /purge(/.*) {
		fastcgi_cache_purge WORDPRESS "$scheme$request_method$host$1"; 
	} 
	location ~* ^.+.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg|jpeg |gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi |wav|bmp|rtf)$ { 
		access_log off; 
		log_not_found off; 
		expires max; 
	} 
	location = /robots.txt { 
		access_log off; 
		log_not_found off; 
	}
	location ~ /. { 
		deny all; 
		access_log off; 
		log_not_found off; 
	} 
}

在 NGINX 中啟用代理緩存

NGINX 還支持對其他代理服務器(由 proxy_pass 指令定義)的響應進行緩存。對於這個測試案例,我們將 NGINX 作為 Node.js Web 應用程序的反向代理,因此我們將啟用 NGINX 作為 Node.js 應用程序的緩存。這裡使用的所有配置指令與前一節中的 FastCGI 指令具有類似的含義,因此我們將不再解釋它們。

為了啟用對代理伺服器的響應緩存,請在頂級 http{} 上下文中包含 proxy_cache_path 指令。要指定如何緩存請求,您還可以添加如下 proxy_cache_key 指令。

proxy_cache_path /var/cache/nginx app1 keys_zone=PROXYCACHE:100m inactive=60m max_size=500m;
proxy_cache_key  "$scheme$request_method$host$request_uri";
add_header X-Cache-Status $upstream_cache_status;
proxy_cache_min_uses 3;

接下來,在位置指令中啟用緩存。

location / {
	proxy_pass http://127.0.0.1:3000;
	proxy_cache        PROXYCACHE;
	proxy_cache_valid 200 302 10m;
	proxy_cache_valid 404      1m;
}

要定義條件,即 NGINX 在哪些情況下不發送緩存的內容,也不從上游伺服器緩存回應,請包含 proxy_cache_bypassproxy_no_cache

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

微調代理緩存性能

以下指令可用於微調代理緩存的性能。它們的含義與 FastCGI 指令相同。

proxy_cache_min_uses 3;
proxy_cache_revalidate on;
proxy_cache_use_stale error timeout updating http_500;
proxy_cache_background_update on;
proxy_cache_lock on;

有關更多信息和緩存配置指令,請參閱兩個主要模塊 ngx_http_fastcgi_modulengx_http_proxy_module 的文檔。

其他資源:NGINX 內容緩存改善 WordPress 性能的技巧

Source:
https://www.tecmint.com/cache-content-with-nginx/