Nginx 緩存兩大核心模式
| 維度 | proxy_cache(反向代理緩存) | fastcgi_cache(FastCGI 緩存) |
| 適用場景 | Nginx 作為前端代理,緩存上游服務器(Tomcat、Node.js、另一台 Nginx)響應 | Nginx 直接連接 PHP-FPM,緩存動態頁面生成結果 |
| 緩存鍵構成 | proxy_cache_key 默認 $scheme$proxy_host$request_uri | fastcgi_cache_key 默認 $scheme$request_method$host$request_uri |
| 典型命中率 | 靜態資源、API 響應:80-95% | 動態頁面(含個性化):30-70% |
| 失效機制 | 需 ngx_cache_purge 模組或緩存時間過期 | 同需第三方模組或依賴過期時間 |
proxy_cache 完整部署流程
1. 編譯安裝 ngx_cache_purge 模組
cd /usr/local/src
wget https://labs.frickle.com/files/ngx_cache_purge-2.3.tar.gz
tar -xzf ngx_cache_purge-2.3.tar.gz
# 重新編譯 Nginx
./configure --prefix=/usr/local/nginx \
--user=www --group=www \
--with-http_ssl_module --with-http_v2_module \
--with-http_stub_status_module \
--add-module=../ngx_cache_purge-2.3
make && make install
2. 創建緩存目錄結構
mkdir -p /data/nginx/proxy_temp
mkdir -p /data/nginx/proxy_cache
chown -R www:www /data/nginx/
# 建議掛載獨立高速磁盤或 tmpfs
3. nginx.conf 核心配置
http {
# 緩存區定義
proxy_temp_path /data/nginx/proxy_temp;
proxy_cache_path /data/nginx/proxy_cache
levels=1:2
keys_zone=proxy_cache_zone:100m
max_size=10g
inactive=24h
use_temp_path=off;
# 可選:緩存鍵自定義
proxy_cache_key "$scheme$request_method$host$request_uri$cookie_user";
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass https://backend_upstream;
proxy_cache proxy_cache_zone;
# 緩存策略
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
proxy_cache_valid any 5m;
# 緩存控制頭
proxy_cache_methods GET HEAD;
proxy_cache_min_uses 1;
proxy_no_cache $cookie_nocache $arg_nocache$arg_comment;
proxy_cache_bypass $cookie_nocache $arg_nocache$arg_comment;
# 傳遞客戶端真實 IP
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
# 添加緩存狀態頭(調試用)
add_header X-Cache-Status $upstream_cache_status;
}
# 手動清理接口(需驗證)
location ~ /purge(/.*) {
allow 127.0.0.1;
allow 10.0.0.0/8;
deny all;
proxy_cache_purge proxy_cache_zone $scheme$request_method$host$1;
}
}
}
關鍵參數詳解
| 參數 | 說明 | 推薦值 |
| levels | 緩存目錄層級,1:2 表示一級兩字符、二級兩字符 | 1:2 |
| keys_zone | 共享內存區名稱:大小,存儲鍵與元數據,100m 約存 80 萬鍵 | 50-200m |
| max_size | 磁盤緩存總量上限,超過則按 LRU 淘汰 | 視磁盤容量 |
| inactive | 未訪問多久刪除,無論是否過期 | 12-48h |
| use_temp_path | off 直接寫入緩存目錄,on 先寫 temp_path 再移動 | off(減少 I/O) |
| proxy_cache_valid | 按狀態碼設置緩存時間 | 200/301/302: 10m-1h |
fastcgi_cache 完整部署流程
1. 創建緩存目錄
mkdir -p /data/nginx/fastcgi_temp
mkdir -p /data/nginx/fastcgi_cache
chown -R www:www /data/nginx/
2. nginx.conf 配置
http {
fastcgi_temp_path /data/nginx/fastcgi_temp;
fastcgi_cache_path /data/nginx/fastcgi_cache
levels=1:2
keys_zone=fastcgi_cache_zone:100m
max_size=5g
inactive=1h
use_temp_path=off;
server {
listen 80;
server_name www.example.com;
root /data/www/example.com;
index index.php;
set $skip_cache 0;
# 不緩存條件
if ($request_method = POST) { set $skip_cache 1; }
if ($query_string != "") { set $skip_cache 1; }
if ($request_uri ~* "/(wp-admin|wp-login|admin|api)") { set $skip_cache 1; }
if ($http_cookie ~* "comment_author|wordpress_logged_in|wp-postpass") { set $skip_cache 1; }
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
fastcgi_pass unix:/run/php/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
# 緩存配置
fastcgi_cache fastcgi_cache_zone;
fastcgi_cache_valid 200 301 302 30m;
fastcgi_cache_valid 404 1m;
fastcgi_cache_key "$scheme$request_method$host$request_uri$cookie_user";
fastcgi_cache_use_stale error timeout invalid_header http_500 http_503;
fastcgi_cache_bypass $skip_cache;
fastcgi_no_cache $skip_cache;
# 緩存狀態頭
add_header X-FastCGI-Cache $upstream_cache_status;
}
# 緩存清理接口
location ~ /purge(/.*) {
allow 127.0.0.1;
deny all;
fastcgi_cache_purge fastcgi_cache_zone "$scheme$request_method$host$1";
}
}
}
緩存清理策略對比
| 方式 | 原理 | 優點 | 缺點 |
| TTL 過期 | inactive/proxy_cache_valid 時間到自動清理 | 零維護、無代碼侵入 | 數據可能不一致、無法即時生效 |
| 主動清理 | 調用 proxy_cache_purge/fastcgi_cache_purge 接口 | 精確控制、即時生效 | 需業務代碼集成、需防濫用 |
| 標籤/版本清理 | 緩存鍵包含版本號,發布時改版本號 | 無需清理接口、天然原子性 | 鍵設計複雜、舊版本佔空間 |
| 全量刷新 | rm -rf /data/nginx/proxy_cache/* | 徹底、簡單 | 瞬間命中率歸零、高峰期禁用 |
監控與調優關鍵指標
# 狀態碼含義
HIT # 命中緩存
MISS # 未命中,已從上游獲取並存入
BYPASS # 命中但配置 bypass 不緩存
EXPIRED # 緩存過期,已重新獲取
STALE # 命中過期緩存(use_stale 生效)
UPDATING # 正在更新緩存(background update)
REVALIDATED # 條件請求驗證後繼續使用
關鍵監控指標
- 命中率 = HIT / (HIT + MISS + EXPIRED) > 80% 為優
- 緩存穿透率 = MISS / (HIT + MISS) < 20%
- 內存區使用率 = keys_zone 實際佔用 / 配置大小 < 90%
- 磁盤使用率 = 實際佔用 / max_size < 85%
生產環境避坑指南
- 緩存鍵包含用戶標識:避免不同用戶看到彼此緩存(如購物車、個人中心)
- Set-Cookie 响應不緩存:
proxy_hide_header Set-Cookie 或 fastcgi_hide_header Set-Cookie
- 避免緩存重定向循環:
proxy_cache_valid 301 302 1h 但需配合 proxy_redirect off
- 大文件不緩存:
proxy_max_temp_file_size 100m 限制緩存體積
- 分離緩存磁盤:掛載獨立 NVMe/SSD,避免與系統盤、數據盤爭搶 I/O
總結
Nginx 雙緩存體系(proxy_cache + fastcgi_cache)構建了從邊緣到應用的多層緩存防線。核心在於:合理設計緩存鍵、精準控制緩存條件、建立高效清理機制、持續監控關鍵指標。配合 ngx_cache_purge 模組實現精確失效,將動態應用性能提升 5-20 倍,是高併發架構不可或缺的基礎設施。