架構模式:Nginx (反向代理 + proxy_cache) + 後端動態應用
| 維度 | Nginx proxy_cache | Varnish |
|---|---|---|
| 儲存介質 | 硬碟(SSD/HDD) | 記憶體(malloc/檔案映射) |
| 緩存容量 | 受限於磁碟(TB 級輕鬆) | 受限於記憶體(通常 < 64GB) |
| 持久化 | 原生支援,重啟不丟 | 需額外配置持久化,複雜且效能折損 |
| 運維複雜度 | 極低(Nginx 核心功能) | 獨立組件,額外學習曲線、監控、升級 |
| 效能(熱數據全在記憶體) | OS Page Cache 自動吸收熱數據,接近記憶體速度 | 純記憶體,極致低延遲 |
| 成本 | 極低(通用硬體) | 高(大記憶體伺服器) |
結論:除非你是「大記憶體富豪」且追求極致微秒級延遲,Nginx proxy_cache + SSD + OS Page Cache 是 99% 場景的最優解。
# http 上下文:定義緩存區
proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=app_cache:100m inactive=7d max_size=50g use_temp_path=off;
# 可選:獨立 temp_path(必須同檔案系統,否則 rename 跨裝置失敗)
# proxy_temp_path /data/nginx/tmp;
server {
listen 80;
server_name app.example.com;
location / {
proxy_pass https://backend_upstream;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# ===== 緩存核心指令 =====
proxy_cache app_cache;
proxy_cache_key "$scheme$request_method$host$request_uri$args"; # 含查詢字串
proxy_cache_valid 200 302 10m; # 正常回應緩存 10 分鐘
proxy_cache_valid 404 1m; # 404 緩存 1 分鐘(防穿透)
proxy_cache_valid any 1m; # 其他狀態碼 1 分鐘
proxy_cache_min_uses 1; # 首次請求即緩存
proxy_cache_methods GET HEAD; # 僅緩存 GET/HEAD
# 可選:忽略後端不緩存頭(謹慎使用)
# proxy_ignore_headers Cache-Control Expires Set-Cookie;
# proxy_hide_header Set-Cookie; # 不向客戶端透傳 Cookie
# 可選:緩存狀態標頭(前端除錯用)
add_header X-Cache-Status $upstream_cache_status;
}
# ===== 互動頁面:登入用戶/帶 Cookie 不緩存 =====
location /user/ {
# 方案 A:完全不緩存
proxy_cache off;
proxy_pass https://backend_upstream;
...
}
location /comment/ {
# 方案 B:短緩存(5-15 分鐘),平衡互動性與效能
proxy_cache app_cache;
proxy_cache_valid 200 302 5m;
proxy_cache_key "$scheme$request_method$host$request_uri$args$cookie_userid";
...
}
# ===== 手動清除緩存(需 ngx_cache_purge 模組)=====
location ~ /purge(/.*) {
allow 10.0.0.0/8;
allow 127.0.0.1;
deny all;
proxy_cache_purge app_cache "$scheme$request_method$host$1$is_args$args";
}
}
| 指令 | 作用 | 調優建議 |
|---|---|---|
proxy_cache_path | 定義緩存區:路徑、目錄層級、共享記憶體區、非活躍過期、最大體積 | keys_zone 大小 = 預估對象數 × 1KB(100m ≈ 10萬對象);inactive 視內容更新頻率;max_size 留 20% 餘量 |
proxy_cache_key | 緩存鍵,決定何時命中/區分 | 預設 $scheme$proxy_host$request_uri;含 $args 區分查詢參數;含 $cookie_xxx 區分用戶個性化內容 |
proxy_cache_valid | 按狀態碼設定 TTL | 200/302 業務容忍度;301/304 較長;404 短防穿透;any 兜底 |
proxy_cache_min_uses | 最少請求次數才緩存 | 1 即首次緩存;>1 可過濾冷數據,但首次訪問慢 |
proxy_cache_methods | 允許緩存的 HTTP 方法 | 預設 GET HEAD;勿加 POST(除非冪等且無副作用) |
proxy_cache_bypass | 條件繞過緩存直接回源 | proxy_cache_bypass $cookie_nocache $arg_nocache; 客戶端可控 |
proxy_no_cache | 條件不存入緩存 | proxy_no_cache $cookie_sessionid; 登入態不緩存 |
| 策略 | 實現 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|---|
| 完全不緩存 | proxy_cache off 或 proxy_no_cache $cookie_loggedin | 數據絕對即時 | 後端壓力大,無緩存收益 | 支付、下單、個人中心 |
| 短 TTL 緩存 | proxy_cache_valid 200 5m + proxy_cache_key ...$cookie_userid | 大幅降低後端壓力,用戶幾分鐘內見到更新 | 極短時間內可能見舊數據 | 評論區、動態餵流、商品列表 |
| 主動失效 | ngx_cache_purge 模組 + 業務發布時調用 PURGE API | 即時生效,緩存收益最大 | 需開發配合、增加系統複雜度 | 文章發布、價格變更、庫存更新 |
若架構為 Nginx + PHP-FPM(無獨立應用伺服器),可直接用 fastcgi_cache 緩存 FastCGI 回應:
fastcgi_cache_path /data/nginx/fcgi_cache levels=1:2 keys_zone=fcgi_cache:50m inactive=1d max_size=20g;
location ~ \.php$ {
fastcgi_pass unix:/run/php/php-fpm.sock;
fastcgi_cache fcgi_cache;
fastcgi_cache_key "$scheme$request_method$host$request_uri$args";
fastcgi_cache_valid 200 10m;
fastcgi_cache_bypass $cookie_nocache $arg_nocache;
fastcgi_no_cache $cookie_sessionid;
add_header X-FastCGI-Cache $upstream_cache_status;
include fastcgi_params;
}
實測對比:同樣硬體,proxy_cache (Nginx + 獨立應用) 負載穩定在 0.4 以下;fastcgi_cache (LNMP) 負載 0.3-0.8 波動較大。原因在於 PHP-FPM 進程模型與 Nginx Worker 爭搶 CPU/上下文切換。
/dev/nvme0n1p1 /data/nginx/cache ext4 defaults,noatime,discard 0 0proxy_cache_lock on; proxy_cache_lock_timeout 5s; proxy_cache_lock_age 5s; 同一鍵並發僅一請求回源。curl -s -o /dev/null 熱門 URL。$upstream_cache_status (HIT/MISS/BYPASS/EXPIRED/STALE/UPDATING) 統計命中率,目標 > 90%。log_format cache '$upstream_cache_status $request_uri $upstream_response_time';Nginx proxy_cache 以硬碟為緩存介質、OS Page Cache 為加速層、共享記憶體區為索引的三層架構,實現了極低成本、極高容量、接近記憶體速度的緩存能力。配合業務感知的緩存鍵設計、差異化 TTL、主動失效機制,可將動態應用轉化為高性能靜態服務,是中小型架構「以小博大」的核心利器。