批量推送PURGE请求清理缓存的核心是适配不同CDN/反向代理的规范:Nginx需启用purge模块并配置VCL,Cloudflare用POST/purge_cache API,阿里云等需调用签名OpenAPI,Varnish须在VCL中显式允许PURGE且限制IP;脚本需校验URL、去重、并发控制、状态码反馈,并配合源站更新、缓存头设置与结果监控。

批量推送 PURGE 请求清理旧缓存,核心是构造符合 CDN 或反向代理(如 Nginx、Varnish、Cloudflare、阿里云全站加速等)要求的 HTTP PURGE 请求,并安全、可控地批量执行。关键不在于“写个脚本”,而在于:明确目标缓存系统是否支持 PURGE、是否需要鉴权、URL 是否需规范化、是否要避免误删、是否需重试与结果校验。
确认目标缓存系统是否真正支持 PURGE
不是所有服务都默认开启或允许 PURGE 方法:
- Nginx 需启用 ngx_http_proxy_cache_purge 模块(开源版不自带,需编译时添加;Tengine 或 OpenResty 原生支持)
- Cloudflare 不支持 PURGE 方法,要用 POST /purge_cache API + Bearer Token
- 阿里云全站加速、腾讯云 CDN 等均提供专属 API(非标准 PURGE),需调用其 OpenAPI 并签名
- Varnish 默认支持 PURGE,但需在 VCL 中显式允许(
if (req.method == "PURGE") { return(purge); })并限制来源 IP
编写安全可控的批量 PURGE 脚本(以 Nginx proxy_cache 为例)
假设你已确认 Nginx 开启了 purge 模块,且只允许内网 IP 执行 PURGE。以下是一个带基础防护的 Bash 脚本示例:
#!/bin/bash
# purge_batch.sh —— 安全批量清理 Nginx 缓存
# 使用前:确保 curl 已安装;目标 Nginx 的 purge_location 已配置且仅限可信源
<p>NGINX_HOST="<a href="https://www.php.cn/link/ca904c1dfe5c1e4415ce964959278c45">https://www.php.cn/link/ca904c1dfe5c1e4415ce964959278c45</a>"
PURGE_LIST="urls_to_purge.txt" # 每行一个完整 URL,如 <a href="https://www.php.cn/link/ca904c1dfe5c1e4415ce964959278c45/assets/logo.png">https://www.php.cn/link/ca904c1dfe5c1e4415ce964959278c45/assets/logo.png</a>
CONCURRENCY=5
DELAY_MS=100</p><h1>校验文件存在且非空</h1><p>[ ! -s "$PURGE_LIST" ] && echo "错误:$PURGE_LIST 为空或不存在" && exit 1</p><h1>逐行读取、去重、过滤空行和注释</h1><p>mapfile -t urls < <(sed '/^[[:space:]]<em>#/d; /^[[:space:]]</em>$/d' "$PURGE_LIST" | sort -u)</p><div class="aritcle_card flexRow">
<div class="artcardd flexRow">
<a class="aritcle_card_img" href="/xiazai/skill3427" title="Nginx Config Linter"><img
src="https://img.php.cn/upload/skill/000/000/081/178955659937208.jpg" alt="Nginx Config Linter" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a href="/xiazai/skill3427" title="Nginx Config Linter">Nginx Config Linter</a>
<p>对 Nginx 配置文件进行语法检查、验证和安全、性能审计。</p>
</div>
<a href="/xiazai/skill3427" title="Nginx Config Linter" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a>
</div>
</div><p>echo "即将清理 ${#urls[@]} 个 URL(去重后),使用并发 $CONCURRENCY..."</p><h1>并发执行(用 xargs 控制并发数)</h1><p>printf '%s\n' "${urls[@]}" | \
xargs -I{} -P "$CONCURRENCY" sh -c '
url="$1"</p><h1>提取 path(PURGE 通常只传 path,不带 scheme/host)</h1><pre class="brush:php;toolbar:false;">path=$(echo "$url" | sed "s|https\?://[^/]*||")
[ -z "$path" ] && echo "跳过非法 URL: $url" && exit 0
# 发起 PURGE 请求(-I 表示忽略响应体,-w "%{http_code}" 输出状态码)
code=$(curl -s -o /dev/null -w "%{http_code}" -X PURGE "$url" -H "Cache-Control: no-cache")
echo "[$code] $url"
# 可选:延迟避免冲击
sleep 0.$2' _ {} "$DELAY_MS"
echo "批量 PURGE 完成。"
更通用的做法:统一走 API 封装(推荐用于生产)
直接发 PURGE 易出错(协议不一致、权限失控、无审计日志)。建议封装为轻量服务或用 Python 脚本调用官方接口:
- 用 Python + requests,读取 CSV/JSON 中的 URL 列表,按服务商类型分发请求
- 对 Cloudflare:POST 到
https://api.cloudflare.com/client/v4/zones/{zone_id}/purge_cache,body 含{"files": ["https://..."]} - 对阿里云:调用
DescribeRefreshTasks+RefreshObjectCaches,需 AccessKey 签名 - 每请求加超时(
timeout=(3, 10))、重试(最多 2 次)、记录失败 URL 到failed.log - 加开关控制:dry-run 模式只打印不发送;--confirm 强制交互确认
必须同步做的几件事
光清缓存不够,否则用户可能看到空白或旧内容:
- 检查源站是否已更新资源:脚本运行前确认新版本文件已上线(如比对 ETag、MD5 或通过部署流水线触发)
-
设置合理的缓存头:确保新资源返回
Cache-Control: public, max-age=31536000, immutable(静态资源),避免反复 PURGE - 监控 PURGE 结果:记录 HTTP 状态码(200/204 成功,404 表示未缓存,405 表示方法禁用,403 表示鉴权失败)
-
避免全站误清:不要用
PURGE /*或通配符;优先按路径前缀或标签(tag-based purge)清理,而非暴力扫 URL

















