本文提供一套生产级的 Nginx 反代缓存配置,用于加速 WordPress 站点。配置分为 HTTP 段(定义全局缓存策略)和 Server 段(应用具体规则),并重点提示如何根据你自己的 WordPress 伪静态规则 调整匹配模式。
一、HTTP 段完整配置
将以下代码放入 Nginx 主配置文件 nginx.conf 的 http { ... } 块中(注意修改缓存路径)。
# 作者:站长帮(WenM)
# --- 【HTTP 段】反代规则开始 ---
## 1. 检查 Cookie
map $http_cookie $cookie_skip {
default 0;
~wordpress_logged_in 1;
~comment_author 1;
~wp-postpass 1;
~woocommerce_items_in_cart 1;
}
## 2. 检查 URI
map $request_uri $uri_skip {
default 0;
~^/wp-admin/ 1;
}
## 3. 检查请求方法
map $request_method $method_skip {
default 0;
POST 1;
}
## 4. 【核心】聚合所有跳过条件
map "$cookie_skip:$uri_skip:$method_skip" $final_skip_cache {
"~1" 1; # 只要字符串中包含 1,就跳过缓存
default 0;
}
# 定义缓存路径 (名称为 sitecache,注意修改/www/wwwroot/site路径为反代网站实际目录)
proxy_cache_path /www/wwwroot/site/proxy_cache_dir levels=1:2 keys_zone=sitecache:20m inactive=1d max_size=5g;
# --- 【HTTP 段】反代规则结束 ---
二、HTTP 段核心讲解
HTTP 段主要完成两件事:定义“跳过缓存”的条件 和 声明缓存存储区域。
1. 三个 map 变量
| 变量 | 检测对象 | 跳过条件(值为 1) |
|---|---|---|
$cookie_skip | Cookie | 包含 wordpress_logged_in(登录)、comment_author(评论者)、wp-postpass(密码保护)、woocommerce_items_in_cart(购物车) |
$uri_skip | 请求 URI | 以 /wp-admin/ 开头(后台地址) |
$method_skip | 请求方法 | POST(提交表单、登录、评论等) |
任何一条匹配,对应变量就会变成 1,表示“应该跳过缓存”。
2. 聚合变量 $final_skip_cache
map "$cookie_skip:$uri_skip:$method_skip" $final_skip_cache {
"~1" 1;
default 0;
}
- 它将三个变量的值拼接成一个字符串(例如
"1:0:1")。 - 正则
"~1"表示只要字符串中含有字符1,结果就是1。 - 最终 Server 段中通过
proxy_cache_bypass $final_skip_cache和proxy_no_cache $final_skip_cache统一控制是否缓存。
3. 缓存存储路径
proxy_cache_path /www/wwwroot/site/proxy_cache_dir levels=1:2 keys_zone=sitecache:20m inactive=1d max_size=5g;
- 务必修改
/www/wwwroot/site为你的实际目录,例如/home/wordpress。 keys_zone=sitecache:20m:缓存键共享内存名称和大小(20M 大约存储 20 万个 key)。inactive=1d:文件 1 天未被访问则自动删除。max_size=5g:磁盘缓存上限 5GB,可按需调整。
💡 HTTP 段配置一次后全局生效。如果你的服务器有多个站点,可以定义多个
proxy_cache_path并用不同的keys_zone名称区分。
三、Server 段完整配置
以下代码放入站点的 server { ... } 块中(例如 /etc/nginx/conf.d/your-site.conf)。请务必将 set $backend 改为你的源站域名。
# 作者:站长帮(WenM)
# --- 【Server 段】应用规则 ---
# 安全过滤:拦截常见的自动化扫描程序后缀,直接返回 404
# 拦截:执行脚本(py/sh/pl)、备份文件(zip/sql/bak)、系统文件(ini/log/env)等
location ~* \.(aspx?|jsp|py|sh|pl|perl|sql|bak|old|save|swp|git|env|log|config|ini|conf|zip|rar|tar|gz|7z|bz2|xz)$ {
return 404;
# access_log off;
# log_not_found off;
}
# 拦截以点开头的隐藏文件 (如 .git, .env, .htpasswd)
location ~* /\.(?!well-known\/) {
return 404;
# access_log off;
# log_not_found off;
}
# 拦截一些不需要公开的目录
location ~* ^/(wp-json/wp/v2/users|wp-content/languages|wp-content/cache) {
return 404;
}
# proxy_http_version 2; # H2 回源(仅 Nginx 1.30.0 以上版本支持)
proxy_http_version 1.1;
proxy_set_header Connection ""; # 清除 Connection 头以支持长连接/H2
proxy_ssl_server_name on;
proxy_ssl_protocols TLSv1.2 TLSv1.3;
set $backend "https://site.com"; # 这里填入正确的源站域名
# 缓存刷新接口,需要 Nginx 支持 ngx_cache_purge 模块
location ~ /purge(/.*) {
allow 127.0.0.1; # 允许访问的 IP(根据需要修改)
deny all;
proxy_cache_purge sitecache "$host$1$is_args$args";
}
# 1. PHP 不缓存
location ~ \.php$ {
proxy_pass $backend;
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_bypass 1;
proxy_no_cache 1;
}
# 2. 静态资源独立缓存
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|webp|avif|woff|woff2|ttf|otf)$ {
proxy_pass $backend;
proxy_set_header Host $host;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 核心:忽略源站 Header,强制长缓存
proxy_ignore_headers Cache-Control Expires;
proxy_cache sitecache;
proxy_cache_key $host$uri$is_args$args;
# 静态资源缓存 120 天
proxy_cache_valid 200 302 120d;
proxy_cache_valid 404 1m;
# 判断是否缓存
proxy_cache_bypass $final_skip_cache;
proxy_no_cache $final_skip_cache;
# 浏览器端缓存控制
expires 365d;
add_header Cache-Control "public, no-transform";
add_header X-Cache-Status $upstream_cache_status;
access_log off;
error_log off;
}
# 3. HTML 页面缓存
location ~* \.html$ {
proxy_pass $backend;
# --- IP 转发配置开始 ---
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;
# --- IP 转发配置结束 ---
# 忽略源站 Header,如未启用登录/评论功能可添加忽略 Set-Cookie,缓存命中率更高
proxy_ignore_headers Cache-Control Expires;
proxy_cache sitecache;
proxy_cache_key $host$uri$is_args$args;
# HTML 缓存 24 小时
proxy_cache_valid 200 302 24h;
proxy_cache_valid 404 1m;
# 判断是否缓存
proxy_cache_bypass $final_skip_cache;
proxy_no_cache $final_skip_cache;
# 浏览器端缓存控制
expires 3m;
add_header Cache-Control "public, no-transform";
# 临时添加,用于观察 Key 的结构
# add_header X-Cache-Key-Debug "$host$uri$is_args$args";
add_header X-Cache-Status $upstream_cache_status;
}
# 4. 特定路径匹配(优先级低于 .html)
# 匹配:首页 /、/about、/privacy-policy
location ~* ^/(|about/?|privacy-policy/?)$ {
proxy_pass $backend;
# --- IP 转发配置开始 ---
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;
# --- IP 转发配置结束 ---
proxy_ignore_headers Cache-Control Expires;
proxy_cache sitecache;
proxy_cache_key $host$uri$is_args$args;
# 缓存 4 小时
proxy_cache_valid 200 302 4h;
proxy_cache_valid 404 1m;
# 判断是否缓存
proxy_cache_bypass $final_skip_cache;
proxy_no_cache $final_skip_cache;
# 浏览器端缓存控制
expires 3m;
add_header Cache-Control "public, no-transform";
add_header X-Cache-Status $upstream_cache_status;
}
# 5. 特定分类匹配(优先级低于上述规则)
location ~* ^/(page|tag)/ {
proxy_pass $backend;
# --- IP 转发配置开始 ---
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;
# --- IP 转发配置结束 ---
proxy_ignore_headers Cache-Control Expires;
proxy_cache sitecache;
proxy_cache_key $host$uri$is_args$args;
# 缓存 12 小时
proxy_cache_valid 200 302 12h;
proxy_cache_valid 404 1m;
# 判断是否缓存
proxy_cache_bypass $final_skip_cache;
proxy_no_cache $final_skip_cache;
# 浏览器端缓存控制
expires 3m;
add_header Cache-Control "public, no-transform";
add_header X-Cache-Status $upstream_cache_status;
}
# 6. 其它页面缓存(5 秒短暂缓存)
location / {
proxy_pass $backend;
# --- IP 转发配置开始 ---
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;
# --- IP 转发配置结束 ---
proxy_cache sitecache;
proxy_cache_key $host$uri$is_args$args;
# 强制忽略源站 Header,确保微缓存不受 WP 插件干扰
proxy_ignore_headers Cache-Control Expires;
# 5 秒微缓存 (抗 CC)
proxy_cache_valid 200 301 302 5s;
proxy_cache_valid 404 1m;
# 判断是否缓存
proxy_cache_bypass $final_skip_cache;
proxy_no_cache $final_skip_cache;
# 容错与调试
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
add_header X-Cache-Status $upstream_cache_status;
}
# --- 【Server 段】应用规则结束 ---
四、Server 段核心讲解
Server 段按照 请求类型 和 URI 特征 将流量分为多个 location 块,每一块都有独立的缓存时长和策略。Nginx 按照 自上而下 的顺序匹配,因此顺序很重要。
1. 安全过滤(开头三个 location)
| 规则 | 作用 |
|---|---|
\.(aspx?|jsp|py|...)$ | 拦截脚本、备份、压缩包等后缀,返回 404 |
/\.(?!well-known\/) | 拦截以点开头的隐藏文件(如 .git, .env) |
^/(wp-json/wp/v2/users|wp-content/languages|...) | 屏蔽 WP 敏感目录,防止信息泄露 |
可根据实际需求增删后缀或路径。
2. 回源基础配置
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_ssl_server_name on;
set $backend "https://site.com"; # 改为你的源站域名
- 使用 HTTP/1.1 并清除
Connection头,支持 keepalive 复用连接。 proxy_ssl_server_name on与 SNI 相关,如果源站是 HTTPS 且多域名,建议开启。- 务必修改
$backend变量,例如set $backend "https://example.com";
3. 分层缓存策略(按优先级排序)
① PHP 请求(location ~ \.php$)
- 不缓存,直接透传。因为 WordPress 所有动态请求(
index.php)都是 PHP 文件。 - 设置
proxy_cache_bypass 1和proxy_no_cache 1强制绕过缓存。
② 静态资源(\.(js|css|png|...)$)
- 缓存 120 天,并忽略源站的
Cache-Control。 - 浏览器端
expires 365d,适合永久不变化的资源。 - 关闭访问日志(
access_log off)减少磁盘 IO。
③ HTML 页面(location ~* \.html$)
- ⚠️ 注意:WordPress 默认不生成
.html静态文件,此规则用于源站已有真正 .html 页面(例如某些缓存插件生成的静态文件)。如果你的 WP 没有这种文件,可以删除或注释此块。 - 缓存 24 小时,浏览器缓存 3 分钟。
④ 特定路径(^/(|about/?|privacy-policy/?)$)
- 手动指定重要页面(首页、关于页等)缓存 4 小时。
- 优先级高于后面的通用规则。
⑤ 分类/标签页面(^/(page|tag)/)
- 针对分页和标签归档,缓存 12 小时。
⑥ 兜底规则(location /)
- 匹配所有其他请求(文章页、存档页、搜索页等)。
- 使用 5 秒微缓存,仅用于抵御突发流量(CC 攻击),不影响用户看到最新内容。
- 开启
proxy_cache_use_stale,在源站故障时依然返回过期缓存,提高可用性。
4. 关于 proxy_ignore_headers 和 proxy_cache_bypass
proxy_ignore_headers Cache-Control Expires;:忽略源站返回的Cache-Control和Expires,让 Nginx 完全按照proxy_cache_valid来决定缓存时长。这样可以避免 WordPress 插件(如发送no-cache)导致缓存失效。proxy_cache_bypass $final_skip_cache和proxy_no_cache $final_skip_cache:当用户登录、访问后台或发送 POST 请求时,$final_skip_cache=1,此时完全不使用缓存,保证动态数据的实时性。
五、总结与建议
1. 必须修改的几处配置
| 位置 | 内容 | 说明 |
|---|---|---|
| HTTP 段 | proxy_cache_path /www/wwwroot/site/... | 改为你服务器的缓存目录 |
| Server 段 | set $backend "https://site.com"; | 改为源站实际域名(含 https:// 或 http://) |
| Server 段 | location ~* ^/(|about/?|privacy-policy/?)$ | 根据你的重要页面修改(支持正则) |
2. 针对 WordPress 伪静态规则的适配提示
WordPress 的伪静态有多种实现方式,直接影响到哪些请求应该被缓存。常见的几种:
| 伪静态形式 | 示例 URL | 对应的 Nginx 匹配 |
|---|---|---|
| Plain(普通) | /?p=123 | 由 location / 处理,因为不带后缀 |
| PATHINFO | /index.php/2025/08/hello-world/ | 会被 location ~ \.php$ 匹配,需要单独处理(通常不缓存) |
| HTML 伪静态(带 .html) | /hello-world.html | 可被 location ~* \.html$ 匹配并缓存 |
| 自定义 Rewrite 规则 | /product/category/name/ | 通常落入 location / 的 5 秒微缓存 |
建议根据你的固定链接设置,调整 Server 段中的 location 匹配规则:
- 如果你使用了 「伪静态 + .html」,保留
location ~* \.html$并调整缓存时长。 - 对于文章页(例如
/%postname%/形式),默认会被最后的location /处理,5 秒微缓存可能不够用。你可以为它单独添加一个规则,例如:location ~* ^/[^/]+/?${ 此处省略了反代规则 }
3. 调试与监控
- 响应头中
X-Cache-Status会显示HIT(命中缓存)、MISS(未命中)、BYPASS(强制跳过)。 - 打开临时调试头(已注释)
add_header X-Cache-Key-Debug "$host$uri$is_args$args";可以查看缓存 key 的构成。 - 使用
curl -I https://your-site.com/查看缓存效果。
4. 性能与安全性
- 安全性:开头的安全过滤能阻止大量扫描和备份文件泄露,建议保留。
- 性能:静态资源缓存 120 天 + 浏览器缓存 365 天,可显著降低回源请求。
- 微缓存:5 秒的全局缓存足以抵挡小规模 CC 攻击,同时不影响动态交互。
希望这篇配置详解能帮助你搭建一个高效、安全的 WordPress 反向代理。
