5月28日 08:26

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%

nginx
gzip 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.240.96-1.36生态完善,流量包折扣大
腾讯云0.20-0.250.96-1.20免费额度多,适合中小业务
七牛云0.18-0.29-图片处理能力强
Cloudflare免费起步Pro $20/月海外节点多,国内速度一般

策略四:多 CDN 架构

单一 CDN 供应商存在两个问题:一是议价空间有限,二是可用性风险集中。多 CDN 不是大公司才需要,日流量超过 10TB 就值得考虑。

实现方式:

  1. DNS 层面:用 CNAME 指向多个 CDN,做加权轮询。缺点是切换延迟较高(DNS 缓存 TTL)
  2. 智能调度:根据用户位置、CDN 节点负载、实时成本选择最优路径。DNSPod、NS1 等支持按策略解析
  3. 按内容类型分配:静态资源走便宜 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 替代 Gzip20%-30% 文本流量

优化优先级建议:先做缓存命中率和图片优化(投入小、见效快),再做计费方式调整和视频编码升级(需要一定技术投入),最后考虑多 CDN 架构(架构改动大)。

面试中回答这个问题,核心要传达三点:一是理解 CDN 成本的结构性差异(流量是大头,优化重心在这里),二是掌握分层优化思路(缓存 → 内容 → 计费 → 架构),三是能给出量化的优化预期(不是笼统的"能省钱",而是"缓存命中率从 X 提升到 Y 可以节省 Z% 的流量成本")。追问方向通常涉及缓存一致性如何保证、多 CDN 的流量调度怎么实现、如何平衡成本和性能——这三个问题想清楚,这个话题基本就过了。

标签:CDN