一、背景与问题
现象
- RUM 显示 98% 请求 FCP<1.2s,但 CDN 日志显示 3.2% 请求回源耗时>2s
- 拨测节点显示「缓存命中率 97%」,但故障时拨测永远显示 200
- 错误监控显示「资源加载失败率 0.5%」,实际业务侧却收到 1.2% 的 503
已尝试
- 检查 Lambda@Edge 缓存策略:发现未设置
Cache-Control: no-cache对动态接口 - 验证 CDN 缓存过期时间:静态资源 TTL=24h,API 响应 TTL=30s(实际被覆盖为 1h)
- 检查 RUM 配置:未开启「缓存命中统计」维度
二、核心原理
1. 缓存污染的双向性
CDN 缓存状态会同时影响:
- 前端监控:RUM 无法区分「缓存响应」与「真实响应」,导致 FCP、LCP 指标失真
- 日志系统:CDN 日志记录的是最终响应码,无法反推缓存链路
- 拨测工具:模拟的是「无缓存」状态,与真实用户体验存在偏差
2. 缓存策略的维度错配
Lambda@Edge 缓存策略未区分:
| 资源类型 | 预期缓存策略 | 实际策略 |
|---|---|---|
| 静态资源 | Cache-Control: max-age=86400 | 正确配置 |
| API 响应 | Cache-Control: no-cache | 被 CDN 默认策略覆盖为 max-age=3600 |
三、架构与实现细节
1. 缓存态对账架构
graph TD
A[前端请求] --> B{CDN 缓存命中?}
B -->|是| C[缓存响应]
B -->|否| D[回源请求]
C --> E[记录缓存命中日志]
D --> F[记录回源日志]
E --> G[RUM 监控]
F --> H[RUM 监控]
G --> I[对比 CDN 日志]
H --> I
2. 关键配置
# Lambda@Edge 缓存策略(CloudFront)
Cache-Control: public, max-age=0, s-maxage=3600
# 区分静态资源与动态接口
<If-None-Match>"abc123"> # 静态资源
Cache-Control: public, max-age=86400
</If-None-Match>
<If-None-Match>"xyz456"> # 动态接口
Cache-Control: no-cache, must-revalidate
</If-None-Match>
四、关键代码与配置
1. RUM 配置增强
// AWS Amplify RUM 配置
const rum = new AWSCloudFrontRUM({
// ... 其他配置
enableCacheHitTracking: true, // 开启缓存命中统计
customEvents: [
{
name: 'cacheHit',
attributes: {
cacheType: 'CDN',
durationMs: 100
}
}
]
});
2. CDN 日志增强
# CloudFront 日志格式增加缓存字段
LogFormat "%{X-Forwarded-For}i %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i" "%{X-Cache}x" "%{X-Cache-TTL}x"
五、踩坑与解决
1. 常见陷阱
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 拨测永远显示 200 | 模拟的是无缓存状态 | 配置拨测工具使用 Cache-Control: no-cache |
| RUM 无法定位缓存问题 | 未开启缓存命中统计 | 在 RUM 配置中添加 enableCacheHitTracking: true |
| API 响应被缓存 | 未正确设置 Cache-Control: no-cache | 在 Lambda@Edge 中显式设置动态接口策略 |
2. 调优案例
// 优化前
CDN 缓存命中率 97% → 实际业务失败率 1.2%
// 优化后
CDN 缓存命中率 92% → 实际业务失败率 0.3%
六、性能与验证数据
| 指标 | 优化前 | 优化后 | 变化 | |---|---|---|---| | RUM FCP P50 | 1.2s | 1.0s | ↓16.7% | | CDN 回源率 | 3.2% | 1.8% | ↓43.8% | | 业务失败率 | 1.2% | 0.3% | ↓75% | | RUM 缓存命中率 | 85% | 92% | ↑8.2% |
七、对比与选型
1. 监控工具对比
| 工具 | 缓存态支持 | 配置复杂度 | 推荐场景 | |---|---|---|---| |RUM | ✅支持缓存命中统计 | ⭐⭐⭐ | 实时用户体验监控 | |CDN 日志 | ✅支持回源分析 | ⭐⭐⭐⭐ | 基础流量分析 | |拨测工具 | ❌默认无缓存 | ⭐⭐⭐⭐⭐ | 服务可用性验证 |
2. 缓存策略建议
- 静态资源:
Cache-Control: public, max-age=86400 - 动态接口:
Cache-Control: no-cache, must-revalidate - Lambda@Edge:通过
If-None-Match区分资源类型
八、总结与展望
1. 核心结论
- 缓存污染是双向的,需从监控、日志、拨测三端同时治理
- 缓存策略必须显式区分资源类型,避免默认策略覆盖
- RUM 配置需开启缓存命中统计,才能定位真实问题
2. 未来方向
- 探索 A/B 测试:对比「缓存态监控」与「真实态监控」的差异
- 构建缓存链路追踪:在 Lambda@Edge 添加 X-Cache-Trace 头
- 自动化策略校验:通过 CDN 日志校验缓存策略是否生效