CDN 成本过高如何优化?
CDN 账单为什么这么高?
一家中型互联网公司,业务量稳定增长,但 CDN 月费从 8 万涨到了 28 万,涨幅远超业务增速。复盘后发现:缓存命中率只有 72%,图片未做格式转换,视频全部用 H.264 编码,没有做任何成本管控。经过一轮系统优化,月费降回了 11 万。
CDN 成本优化不是省钱,是花该花的钱。下面从成本构成、六大核心优化策略、监控体系三个层面讲清楚。
CDN 成本由哪些部分组成?
理解成本结构是优化的前提。CDN 的费用主要来自五个方面:
| 费用类型 | 计费方式 | 占比(典型场景) |
|---|---|---|
| 流量/带宽 | 按流量(GB)或按带宽峰值(Mbps) | 60%-70% |
| 请求次数 | 按千次请求计费 | 10%-15% |
| HTTPS 证书 | 按证书数量或域名数 | 3%-5% |
| 安全防护(WAF/DDoS) | 按规则数或防护流量 | 5%-10% |
| 边缘计算/视频处理 | 按调用次数或处理时长 | 5%-10% |
流量/带宽是绝对大头,优化重心应该放在这里。计费方式的选择也很关键:流量平稳的业务选按流量计费更划算,有明显峰值波动的(如直播、促销)选按带宽峰值第五计费(95 带宽)更合适。
策略一:缓存命中率提升到 95% 以上
缓存命中率每提升 1 个百分点,回源流量大约减少 3%-5%。命中率从 72% 提升到 95%,仅此一项就能节省 30% 以上的流量成本。
关键配置:
http# 静态资源:长缓存 + immutable Cache-Control: public, max-age=31536000, immutable # API 响应:短缓存,CDN 侧可缓存更久 Cache-Control: public, max-age=60, s-maxage=300 # 用户敏感数据:禁止缓存 Cache-Control: no-store
缓存键优化也很容易被忽略。默认缓存键会包含所有查询参数,但 ?utm_source=xxx 这类追踪参数不影响内容,应该忽略:
nginx# 忽略不影响内容的查询参数 proxy_cache_key "$scheme$request_method$host$uri";
资源版本化是避免缓存失效的常用手段。不要用 style.css?v=2,改成 style.v2.css,旧版本自然过期,不需要手动刷新缓存。
缓存预热适合内容发布场景。新页面上线前,主动将关键资源推送到边缘节点,避免用户首次访问时回源。大部分 CDN 厂商都提供了预热 API,可以在 CI/CD 发布流程中自动调用。
缓存一致性是面试常问的追问点。常见方案有三种:一是 TTL 自然过期(最简单,适合容忍短暂不一致的场景);二是主动 Purge(适合内容更新后必须立即生效的场景,但频繁 Purge 会降低命中率);三是版本化 URL(改 URL 不改内容,最推荐)。实际生产中通常组合使用:静态资源用版本化 URL,动态内容用短 TTL + 关键更新时 Purge。
策略二:内容压缩和格式转换
图片优化:单此一项可减少 50%-70% 流量
| 格式 | 适用场景 | 相比 JPEG 节省 |
|---|---|---|
| WebP | 照片、复杂图形 | 25%-35% |
| AVIF | 对兼容性要求不高的场景 | 40%-50% |
| PNG → WebP | 含透明通道的图 | 60%-70% |
实际操作中,用 CDN 的图片处理服务做实时转换是最省事的方案。Cloudflare 的 Polish、阿里云的图片处理、七牛的 imageView2 都支持按请求参数自动转换格式和压缩质量。这种方式不需要改源站图片,CDN 边缘实时转换,用户请求时自动返回最优格式。
html<!-- 通过 URL 参数请求 WebP 格式 --> <img src="https://cdn.example.com/photo.jpg?format=webp&q=80">
也可以通过 Accept 请求头自动协商:浏览器发送 Accept: image/webp,CDN 自动返回 WebP 格式,无需改业务代码。
文本压缩:Brotli 比 Gzip 再省 20%-30%
nginxgzip on; gzip_types text/plain text/css application/json application/javascript; # Brotli 压缩效果更好,主流浏览器已支持 brotli on; brotli_types text/plain text/css application/json application/javascript; brotli_comp_level 6;
Brotli 在压缩比上优于 Gzip,但压缩速度稍慢。对于静态资源可以预压缩,动态内容用 Gzip 即可。Cloudflare 默认开启 Brotli,阿里云 CDN 需要在控制台手动开启。
视频优化:编码格式选择影响巨大
H.264 是兼容性最好的选择,但从成本角度看,H.265/HEVC 比 H.264 节省约 50% 的码率,AV1 节省约 60%。如果目标用户主要在移动端,可以优先推送 H.265 版本。
自适应码率(ABR)也是必须做的:根据用户带宽动态选择清晰度,避免 4K 视频推给 3G 网络,既浪费流量又卡顿。HLS 和 DASH 协议都原生支持 ABR,配置好码率阶梯即可。
策略三:计费方式优化
很多人只关注 CDN 的单价,但计费方式选错了,再低的价格也省不了钱。
按流量 vs 按带宽峰值:
- 流量平稳、可预测 → 按流量计费
- 有明显高峰(直播、促销、游戏更新)→ 按 95 带宽峰值计费
- 流量波动大但不确定 → 先按流量计费,积累一个月数据再判断
预留带宽/流量包: 各厂商都提供预付费流量包,通常比按量付费便宜 20%-40%。适合流量稳定的业务。阿里云的 CDN 流量包、腾讯云的预付费带宽包都是这个思路。
跨区域费用差异: 国内流量和海外流量价格差 2-5 倍。如果海外用户不多,不需要开全球加速。只开需要的区域,能省不少钱。一个常见误区是开了"全球加速"却 90% 的流量来自国内,多花了好几倍的钱。
主流 CDN 厂商价格对比(国内流量,2026 年参考价):
| 厂商 | 按流量(元/GB) | 按带宽(元/Mbps/天) | 特点 |
|---|---|---|---|
| 阿里云 | 0.20-0.24 | 0.96-1.36 | 生态完善,流量包折扣大 |
| 腾讯云 | 0.20-0.25 | 0.96-1.20 | 免费额度多,适合中小业务 |
| 七牛云 | 0.18-0.29 | - | 图片处理能力强 |
| Cloudflare | 免费起步 | Pro $20/月 | 海外节点多,国内速度一般 |
策略四:多 CDN 架构
单一 CDN 供应商存在两个问题:一是议价空间有限,二是可用性风险集中。多 CDN 不是大公司才需要,日流量超过 10TB 就值得考虑。
实现方式:
- DNS 层面:用 CNAME 指向多个 CDN,做加权轮询。缺点是切换延迟较高(DNS 缓存 TTL)
- 智能调度:根据用户位置、CDN 节点负载、实时成本选择最优路径。DNSPod、NS1 等支持按策略解析
- 按内容类型分配:静态资源走便宜 CDN,动态内容走高性能 CDN,视频走专用 CDN
javascript// 简化的 CDN 选择逻辑 function selectCDN(contentType, userRegion) { const policy = { 'image': { cdn: 'low-cost-cdn', regions: ['cn-east', 'cn-south'] }, 'video': { cdn: 'video-cdn', regions: ['global'] }, 'api': { cdn: 'high-perf-cdn', regions: ['cn-east'] } }; return policy[contentType]?.cdn || 'default-cdn'; }
按内容类型分配 CDN 的成本差异示例: 一家视频平台把图片流量切到低成本的通用 CDN(单价低 40%),视频流量留在专用 CDN,整体成本下降约 25%。
多 CDN 的难点在于缓存一致性管理和流量调度精细化。面试中如果追问,可以从 DNS 切换的延迟问题、缓存预热策略、流量分配比例调整这几个角度展开。
策略五:请求次数优化
请求次数费用容易被忽略,但在高并发场景下占比不低。每千次请求 0.01 元,日请求 10 亿次就是每天 1 万元。
主要优化手段:
- 资源合并:把多个小文件合并成一个,减少请求数。CSS/JS 打包是基本操作
- 雪碧图:小图标合并为一张大图,用 CSS 定位显示。在 HTTP/1.1 下效果明显,HTTP/2 下收益降低
- HTTP/2 多路复用:升级到 HTTP/2 后,多个请求可以复用一个连接,但请求次数仍然计费
- 减少无效请求:404 请求也计费,定期清理失效链接和过期资源
- API 响应合并:多个接口调用合并为一个批量接口,减少 API 请求次数
策略六:成本监控与告警
不做监控的优化都是盲目的。需要关注的指标:
| 指标 | 告警阈值 | 说明 |
|---|---|---|
| 缓存命中率 | < 90% | 低于此值说明缓存策略有问题 |
| 流量环比增长 | > 20% | 短期突增可能是攻击或配置错误 |
| 带宽峰值/均值比 | > 3:1 | 峰值过高说明可以优化计费方式 |
| 4xx/5xx 比例 | > 1% | 错误请求也在花钱 |
成本归因分析也很重要。用 SQL 分析 CDN 日志,找出流量 Top 10 的 URL,看看是不是某个大文件没做压缩,或者某个接口的缓存 TTL 设置太短。
sql-- 查询流量最大的 URL SELECT url, SUM(bytes) as total_bytes, COUNT(*) as requests FROM cdn_logs WHERE date >= CURRENT_DATE - INTERVAL 7 DAY GROUP BY url ORDER BY total_bytes DESC LIMIT 10; -- 查询缓存命中率低的 URL SELECT url, COUNT(*) as total, SUM(CASE WHEN cache_status = 'HIT' THEN 1 ELSE 0 END) / COUNT(*) * 100 as hit_rate FROM cdn_logs WHERE date >= CURRENT_DATE - INTERVAL 7 DAY GROUP BY url HAVING hit_rate < 80 ORDER BY hit_rate;
优化效果汇总
| 优化手段 | 典型节省幅度 | 实施难度 |
|---|---|---|
| 缓存命中率提升(72%→95%) | 30%-40% 流量 | 低 |
| 图片格式转换(JPEG→WebP) | 25%-35% 图片流量 | 低 |
| 视频编码升级(H.264→H.265) | 40%-50% 视频流量 | 中 |
| 计费方式调整 | 10%-30% 总成本 | 低 |
| 多 CDN 架构 | 15%-25% 总成本 | 高 |
| Brotli 替代 Gzip | 20%-30% 文本流量 | 低 |
优化优先级建议:先做缓存命中率和图片优化(投入小、见效快),再做计费方式调整和视频编码升级(需要一定技术投入),最后考虑多 CDN 架构(架构改动大)。
面试中回答这个问题,核心要传达三点:一是理解 CDN 成本的结构性差异(流量是大头,优化重心在这里),二是掌握分层优化思路(缓存 → 内容 → 计费 → 架构),三是能给出量化的优化预期(不是笼统的"能省钱",而是"缓存命中率从 X 提升到 Y 可以节省 Z% 的流量成本")。追问方向通常涉及缓存一致性如何保证、多 CDN 的流量调度怎么实现、如何平衡成本和性能——这三个问题想清楚,这个话题基本就过了。