CDN回源更新后需主动清理边缘节点缓存,可通过OpenResty的Lua脚本按URI等条件精准失效缓存;关键在于缓存键可逆推导路径,需统一规范URI、小写host、避免不可预测变量,并在CI/CD中自动化触发purge接口。

CDN 回源更新后,边缘节点缓存若未及时清理,会导致用户持续看到旧内容。Nginx 本身不提供动态缓存键匹配清理能力,但通过 nginx-lua 模块(如 OpenResty)可实现按 URI、Host、请求头等条件精准触发缓存失效,无需重启或依赖外部服务。
缓存键设计要支持可逆推导
自动清理的前提是能从请求中还原出实际缓存路径。Nginx 默认缓存键由 proxy_cache_key 决定,例如:
proxy_cache_key "$scheme://$host$request_uri";
对应缓存文件路径由 MD5 哈希生成(如 /var/cache/nginx/1/23/ab1234567890... )。Lua 脚本需用相同逻辑计算 key 并转为路径,才能定位并删除。
- 避免在
proxy_cache_key中使用不可预测变量(如时间戳、随机数、未标准化的请求头) - 建议统一规范 URI:对带参数的请求做排序和过滤(如剔除
utm_*、__t=类跟踪参数) - 若使用
$host,注意是否区分大小写;建议统一转小写再参与哈希
用 Lua 实现按 URI 主动清理
在 Nginx 配置中添加一个管理 location(如 /purge),配合 Lua 执行缓存路径计算与文件删除:
location ~ ^/purge(/.*)$ {
allow 127.0.0.1;
allow 10.0.0.0/8;
deny all;
content_by_lua_block {
local uri = ngx.var[1] or "/"
local host = string.lower(ngx.var.host)
local key = "http://" .. host .. uri
local md5 = ngx.md5(key)
local cache_path = "/var/cache/nginx/" .. string.sub(md5, -1) .. "/" .. string.sub(md5, -2, -2) .. "/" .. md5
os.remove(cache_path)
ngx.say("Purged: ", cache_path)
}
}
调用示例:curl -X PURGE http://example.com/purge/index.html。注意该方式仅清理单个 URI,不递归或通配。
配合回源更新流程做自动化触发
缓存清理不应手动执行,而应嵌入发布流水线。常见做法:
- 在 CI/CD 部署脚本末尾,调用 Nginx purge 接口(需确保部署机有访问权限)
- 源站更新成功后,由 Webhook 触发 Lua 脚本批量生成 purge 请求(如遍历变更的 URL 列表)
- 对静态资源加版本号或哈希后缀(如
app.a1b2c3.js),天然规避缓存问题,仅需清理 HTML 等入口文件
若需通配清理(如清空某目录下所有缓存),可扩展 Lua 脚本扫描对应 hash 目录,但要注意 I/O 开销与锁竞争,生产环境慎用。
验证清理是否生效
清理后务必确认响应头和内容已更新:
- 检查
X-Cache或X-Proxy-Cache头是否变为MISSED或BYPASS - 用
curl -I对比清理前后ETag或Last-Modified - 临时关闭缓存(
proxy_cache_bypass 1)对比原始源站响应,排除 CDN 中间层干扰
不复杂但容易忽略:确保 Nginx worker 进程对缓存目录有读写权限,且 proxy_cache_path 定义的路径与 Lua 中硬编码路径完全一致。










