Nginx中fastcgi_cache實現(xiàn)PHP頁面緩存加速
在 Nginx 中使用 fastcgi_cache 可以緩存 PHP-FPM 生成的動態(tài)頁面,顯著降低后端負載并提升響應速度。以下是完整的配置方案和優(yōu)化技巧。
核心配置架構
用戶請求 → Nginx → 檢查緩存 → [命中] 直接返回緩存
↓
[未命中] → PHP-FPM → 生成頁面 → 存入緩存 → 返回用戶
基礎配置
1. http 塊(全局配置)
http {
# 定義緩存區(qū)
fastcgi_cache_path /var/cache/nginx/fastcgi levels=1:2 keys_zone=PHPCACHE:100m max_size=1g inactive=60m use_temp_path=off;
# 緩存鍵定義(區(qū)分 URI 和參數(shù))
fastcgi_cache_key "$scheme$request_method$host$request_uri";
# 默認緩存時間
fastcgi_cache_valid 200 302 10m;
fastcgi_cache_valid 404 1m;
# 日志格式(可選,用于調(diào)試緩存命中率)
log_format cache_log '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'cache:$upstream_cache_status';
}2. server/location 塊(站點配置)
server {
listen 80;
server_name example.com;
root /var/www/html;
index index.php;
# PHP 請求處理
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
# ========== 緩存核心配置 ==========
# 啟用緩存并指定緩存區(qū)
fastcgi_cache PHPCACHE;
# 緩存條件:僅對登錄用戶以外的請求緩存
fastcgi_cache_bypass $cookie_session; # 有 session cookie 時不讀緩存
fastcgi_no_cache $cookie_session; # 有 session cookie 時不寫緩存
# 或者根據(jù)自定義 header 控制(如管理員后臺不緩存)
fastcgi_cache_bypass $http_pragma;
fastcgi_no_cache $http_authorization;
# 緩存狀態(tài)頭(調(diào)試用,生產(chǎn)環(huán)境可移除)
add_header X-Cache-Status $upstream_cache_status;
# 緩存鎖定(防止緩存失效時的并發(fā)穿透)
fastcgi_cache_lock on;
fastcgi_cache_lock_timeout 5s;
# 后臺更新(舊緩存過期時,先返回舊數(shù)據(jù),后臺異步更新)
fastcgi_cache_background_update on;
# 使用 stale 緩存(后端故障時返回過期緩存)
fastcgi_cache_use_stale error timeout invalid_header updating http_500;
}
# 靜態(tài)文件不經(jīng)過 PHP
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 30d;
access_log off;
}
}緩存控制策略詳解
按 Cookie 排除(用戶登錄狀態(tài))
# 如果有 wordpress_logged_in cookie 就不緩存(WordPress 場景)
fastcgi_cache_bypass $cookie_wordpress_logged_in;
fastcgi_no_cache $cookie_wordpress_logged_in;
# 多條件組合(任一滿足即不緩存)
set $skip_cache 0;
if ($cookie_session) { set $skip_cache 1; }
if ($request_method = POST) { set $skip_cache 1; }
if ($query_string != "") { set $skip_cache 1; }
if ($http_authorization) { set $skip_cache 1; }
fastcgi_cache_bypass $skip_cache;
fastcgi_no_cache $skip_cache;按 URL 排除(后臺管理、API)
location ~ /wp-admin|/wp-login|/api/ {
fastcgi_cache off; # 完全禁用緩存
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
include fastcgi_params;
}自定義緩存時間(按頁面類型)
location ~ \.php$ {
fastcgi_cache PHPCACHE;
# 首頁緩存 5 分鐘
if ($request_uri = /) {
set $cache_time 5m;
}
# 文章頁緩存 1 小時
if ($request_uri ~ ^/post/) {
set $cache_time 1h;
}
# 默認 10 分鐘
if ($cache_time = "") {
set $cache_time 10m;
}
fastcgi_cache_valid 200 $cache_time;
}緩存清理方案
方案 1:使用 ngx_cache_purge 模塊(需編譯安裝)
# 編譯時添加 --add-module=ngx_cache_purge
location ~ /purge(/.*) {
allow 127.0.0.1; # 僅允許本地訪問
deny all;
fastcgi_cache_purge PHPCACHE "$scheme$request_method$host$1";
}方案 2:腳本手動清理
#!/bin/bash
# /usr/local/bin/clear-php-cache.sh
CACHE_DIR="/var/cache/nginx/fastcgi"
TARGET="$1"
if [ -z "$TARGET" ]; then
# 清理全部緩存
rm -rf ${CACHE_DIR}/*
echo "All cache cleared"
else
# 根據(jù) URL 計算緩存文件路徑(匹配 fastcgi_cache_key)
KEY="$scheme$request_method$host$TARGET"
MD5=$(echo -n "$KEY" | md5sum | awk '{print $1}')
LEVEL1=${MD5: -1}
LEVEL2=${MD5: -3:2}
rm -f "${CACHE_DIR}/${LEVEL1}/${LEVEL2}/${MD5}"
echo "Cache for $TARGET cleared"
fi
# 重載 Nginx 使更改生效(或發(fā)送信號)
kill -HUP $(cat /var/run/nginx.pid)生產(chǎn)環(huán)境優(yōu)化配置
http {
# 緩存路徑優(yōu)化:SSD 建議用 levels=1:2,機械硬盤用 levels=1:2:3
fastcgi_cache_path /var/cache/nginx/fastcgi
levels=1:2
keys_zone=PHPCACHE:256m # 內(nèi)存中存儲 256MB 的鍵
max_size=10g # 磁盤最大 10GB
inactive=7d # 7 天未訪問則清理
use_temp_path=off # 直接寫入目標目錄,減少 IO
manager_files=10000 # 每次清理最多處理 10000 文件
manager_sleep=50ms # 清理間隔
manager_threshold=200ms; # 單次清理最大耗時
# 忽略后端設置的緩存控制頭(強制按 Nginx 配置緩存)
fastcgi_ignore_headers X-Accel-Expires Expires Cache-Control Set-Cookie;
# 隱藏后端版本信息
fastcgi_hide_header X-Powered-By;
fastcgi_hide_header Server;
}
server {
location ~ \.php$ {
fastcgi_cache PHPCACHE;
fastcgi_cache_valid 200 5m;
# 微緩存(Microcache):極短時間的緩存,應對突發(fā)流量
fastcgi_cache_valid 200 1s; # 1 秒內(nèi)相同請求直接返回緩存
# 緩存鍵增加設備類型(桌面/移動端分開緩存)
fastcgi_cache_key "$scheme$request_method$host$request_uri$http_user_agent";
}
}監(jiān)控與調(diào)試
查看緩存命中率
# 查看緩存目錄統(tǒng)計
find /var/cache/nginx/fastcgi -type f | wc -l
# 實時查看緩存狀態(tài)頭
curl -I http://example.com/page.php
# 檢查響應頭中的 X-Cache-Status: HIT / MISS / BYPASS / EXPIRED
# 分析日志統(tǒng)計命中率
awk '{print $NF}' /var/log/nginx/access.log | sort | uniq -c關鍵響應頭說明
| 狀態(tài) | 含義 |
|---|---|
| HIT | 緩存命中,直接返回 |
| MISS | 緩存未命中,已寫入新緩存 |
| BYPASS | 跳過緩存(如帶有 Cookie) |
| EXPIRED | 緩存過期,已重新獲取 |
| UPDATING | 緩存過期,但返回舊數(shù)據(jù)(后臺更新中) |
| STALE | 返回過期緩存(后端故障時) |
完整 WordPress 優(yōu)化示例
fastcgi_cache_path /var/cache/nginx/wp levels=1:2 keys_zone=WPCACHE:150m max_size=2g inactive=48h;
server {
set $skip_cache 0;
# 不緩存的條件
if ($request_method = POST) { set $skip_cache 1; }
if ($query_string != "") { set $skip_cache 1; }
if ($cookie_woocommerce_items_in_cart) { set $skip_cache 1; } # WooCommerce
if ($cookie_wordpress_logged_in) { set $skip_cache 1; }
if ($request_uri ~* "/wp-admin/|/wp-login|/cart|/checkout|/my-account") { set $skip_cache 1; }
location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
fastcgi_cache WPCACHE;
fastcgi_cache_valid 200 60m;
fastcgi_cache_bypass $skip_cache;
fastcgi_no_cache $skip_cache;
fastcgi_cache_lock on;
fastcgi_cache_use_stale updating error timeout;
add_header X-Cache-Status $upstream_cache_status;
}
}配置完成后,使用 nginx -t 檢查語法,然后 systemctl reload nginx 生效。建議先用小流量測試,確認緩存邏輯符合預期后再全量上線。
到此這篇關于Nginx中fastcgi_cache實現(xiàn)PHP頁面緩存加速的文章就介紹到這了,更多相關Nginx PHP頁面緩存加速內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
通過Nginx實現(xiàn)前端與后端的協(xié)同部署
在現(xiàn)代 web 開發(fā)中,前端與后端的協(xié)同部署是一個關鍵問題,一個高效的部署策略不僅能提升用戶體驗,還能簡化開發(fā)流程,今天,我們就來探討如何利用 Nginx 實現(xiàn)前端與后端的協(xié)同部署,需要的朋友可以參考下2025-03-03
Nginx流量拷貝ngx_http_mirror_module模塊使用方法詳解
這篇文章主要介紹了Nginx流量拷貝,Nginx專門提供了ngx_http_mirror_module模塊,用來實現(xiàn)流量拷貝。將生產(chǎn)環(huán)境的流量拷貝到預上線環(huán)境或測試環(huán)境2022-04-04

