缓存穿透是指请求的数据既不在缓存中也不在数据库中,导致大量无效请求直击数据库;核心解决方案是缓存空值(设置短过期时间)或使用布隆过滤器前置拦截。

移动端特殊请求容易引发缓存穿透,不是因为 Nginx 缓存“失效”,而是这类请求天然携带绕过缓存的特征(如 Cookie、Authorization、动态参数),导致大量请求直击后端。处理核心是:**识别移动端真实意图,区分“该绕”和“不该绕”,再做精细化控制。**
识别移动端典型绕过信号
很多移动端请求默认带以下头或参数,Nginx 会自动 bypass 缓存(即使没配 proxy_cache_bypass):
- Cookie 头:App 登录态、设备 ID、AB 测试分组等,只要存在就默认不缓存
- Authorization 头:JWT Token、Bearer 令牌,常见于用户中心、订单接口
-
动态查询参数:如
?v=1.23.4&t=1727907388或?_r=abc123,让 cache_key 每次都不同 - User-Agent 包含 mobile / iOS / Android:但仅靠 UA 不可靠,易被伪造,不建议单独作为判断依据
对症配置:让“真管理请求”绕过,让“普通用户请求”进缓存
不能一刀切禁用移动端缓存,而要按业务语义拆分:
- 用户列表页(/api/users)—— 需缓存,但 App 带了
Cookie: session=xxx→ 用proxy_ignore_headers Set-Cookie;+proxy_cache_key $scheme$host$uri忽略 Cookie 影响 - 管理员预览页(/api/admin/preview)—— 必须绕过,且防污染 → 同时配:
proxy_cache_bypass $http_x_admin_preview $http_authorization;proxy_no_cache $http_x_admin_preview $http_authorization; - 带版本号的资源(/static/app.js?v=2.1.0)—— 参数无业务意义 → 用
set $cache_uri $uri;+if ($args ~ "v=") { set $cache_uri $uri; }标准化 key
加一层轻量兜底,防雪崩式穿透
当大量移动端请求因参数抖动或头缺失造成 MISS 激增时,光靠缓存策略不够,需配合降级机制:
- 启用
proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504;,后端异常时仍可返回旧缓存 - 对高频接口(如首页数据)开启
proxy_cache_lock on;,避免同一 key 的多个穿透请求同时打到后端 - 用
limit_req zone=mobile burst=10 nodelay;控制单个设备/IP 的突发请求,防爬虫或误配置 SDK 刷垮后端
验证是否真正生效
别只看配置,用真实移动端行为验证:
- 模拟 App 请求:
curl -H "User-Agent: MyApp/2.3.1 (iPhone; iOS 17.6)" -H "Authorization: Bearer xyz" https://api.example.com/api/profile - 检查响应头:
X-Cache-Status: BYP(绕过)、HIT(命中)或MISS(未命中但没绕) - 查 Nginx 日志字段
$upstream_cache_status,连续出现大量MISS就说明 key 设计或头处理有问题











