要实现生产环境特定URL缓存的手动清理,需启用Nginx proxy_cache_purge模块,配置一致的cache key与purge路径,限制IP访问,并通过204响应及响应头、缓存文件三重验证清除效果。

要实现生产环境特定 URL 缓存的手动清理,核心是启用并正确配置 Nginx 的 proxy_cache_purge 模块(通常需编译时显式开启),再通过 HTTP 请求触发对应缓存键的删除操作。关键在于缓存键(cache key)与 purge 请求路径的一致性,否则会“看似成功却未清除”。
确认模块已启用并配置 cache zone
该模块不是 Nginx 默认内置模块,需确认当前 Nginx 版本支持且已编译进二进制(可通过 nginx -V 2>&1 | grep -o with-http-cache-purge-module 验证)。若未启用,需重新编译添加 --with-http_cache_purge_module 参数。
在 http 块中定义缓存区,例如:
proxy_cache_path /var/cache/nginx/proxy levels=1:2 keys_zone=main:10m max_size=1g inactive=60m use_temp_path=off;
其中 keys_zone=main:10m 的名字(此处为 main)后续需在 proxy_cache 和 proxy_cache_purge 指令中保持一致。
设置一致的 proxy_cache_key 与 purge 路径匹配逻辑
proxy_cache_purge 不按原始请求 URL 删除,而是按你定义的 proxy_cache_key 生成的哈希值来匹配。因此 purge 请求的 URI 必须能映射到相同的 key 值。
常见做法是:让 purge 请求走独立 location,并用 proxy_cache_purge 指令绑定同一 cache zone;同时确保被缓存内容的 proxy_cache_key 与 purge 请求的变量组合完全一致。例如:
安装并运行 Aperture(Lightning Labs 的 L402 闪电反向代理),用于创建 L402 付费墙、配置付费 API 端点、为其他代理托管付费内容或测试 L402 认证流程。
proxy_cache_key "$scheme$request_method$host$request_uri";
则 purge 请求应使用完全相同的 scheme、method、host 和 uri(如 PURGE http://example.com/api/v1/user/123)。实际中更推荐统一用 GET + 标准化 URI,避免 method 或 header 差异导致 key 不匹配。
典型 purge location 配置示例:
location ~ /purge(/.*) {
allow 127.0.0.1;
allow 10.0.0.0/8; # 仅允许内网运维 IP
deny all;
proxy_cache_purge main "$scheme$request_method$host$1";
}注意:$1 是正则捕获的路径部分(如访问 /purge/api/v1/user/123,则 $1 为 /api/v1/user/123),必须与缓存 key 中用于标识资源的部分严格对应。
安全执行手动清理操作
生产环境严禁开放无限制的 purge 接口。务必做到:
- 限制访问来源 IP,只允许可信运维网络或跳板机
- 禁用公网直接访问,必要时配合 HTTP Basic Auth(但注意 auth 会影响 cache key,慎用)
- 避免在 location 中混用
proxy_pass,purge location 应只做清理,不转发后端 - 清理前可先用
curl -I -X PURGE http://example.com/purge/xxx测试响应头是否返回204 No Content(成功)或404 Not Found(缓存不存在)或405 Not Allowed(方法/权限问题)
验证缓存是否真正清除
不要仅依赖 purge 返回状态码。建议三步验证:
- 发起一次 purge 请求,确认返回 204
- 立即用 curl 加
-I查看目标 URL 响应头,确认X-Cache(若自定义)或Age变为 0,且Cache-Control中无 stale 标识 - 检查缓存目录(如
/var/cache/nginx/proxy/)对应哈希子目录下文件是否已被删除(需注意文件可能延迟清理,但新请求会重建)
若仍命中旧缓存,请回查 proxy_cache_key 是否含影响一致性的变量(如 $cookie_xxx、$args),或后端返回了不可缓存的 header(如 Cache-Control: private)。

















