•2024年10月
CDNCDN缓存穿透的三种死法
CDN缓存失效导致源站被打爆?这三个坑你踩过几个
死法一:缓存雪崩
场景: 大量缓存同时过期,请求直击源站
# 错误配置
location ~* \.(jpg|png|css|js)$ {
expires 1h; # 所有文件同时过期
}
# 正确配置
location ~* \.(jpg|png|css|js)$ {
expires 1h;
add_header Cache-Control "public, max-age=3600, stale-while-revalidate=300";
}
解决: 设置随机过期时间 + stale-while-revalidate
死法二:热点数据穿透
场景: 热门内容缓存miss,瞬间并发请求源站
// 源站防护
const rateLimit = require('express-rate-limit');
const limiter = rateLimit({
windowMs: 1000, // 1秒
max: 10, // 每秒最多10个请求
keyGenerator: (req) => req.headers['cf-connecting-ip'] || req.ip
});
app.use('/api/hot-data', limiter);
死法三:缓存键冲突
场景: 不同内容使用相同缓存键
# 问题URL
/api/user?id=123×tamp=1642694400
/api/user?timestamp=1642694400&id=123
# 解决方案:标准化查询参数
location /api/ {
set $args_sorted '';
# 使用Lua脚本排序查询参数
rewrite_by_lua_block {
local args = ngx.req.get_uri_args()
local sorted_args = {}
for k, v in pairs(args) do
table.insert(sorted_args, k .. "=" .. v)
end
table.sort(sorted_args)
ngx.var.args_sorted = table.concat(sorted_args, "&")
}
proxy_cache_key $scheme$proxy_host$uri$args_sorted;
}
救命稻草:源站保护
# 限制回源并发
upstream backend {
server 127.0.0.1:8080 max_conns=50;
keepalive 32;
}
# 启用缓存锁
proxy_cache_lock on;
proxy_cache_lock_timeout 5s;
proxy_cache_lock_age 5s;
# 使用陈旧缓存
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
监控告警
# 关键指标
- 缓存命中率 < 90%
- 回源QPS突增 > 基线3倍
- 源站5xx错误率 > 1%
记住:CDN不是万能的,源站保护才是王道。