CDN 接入与 HTTP/2、HTTP/3

CDN 干的事很朴素:把你的静态资源复制到离用户最近的节点,用户就近取,源站只承受回源流量。它对「用户分布广、静态资源多、经不起流量峰值」的站点收益极大,对「用户就在一个城市、全是动态接口」的站点可能只是多了一层排查难度。本章讲接入流程、缓存规则、真实 IP 还原与 HTTP/2、HTTP/3 的现状。

要解决的问题

  • 我这个站到底需不需要 CDN?
  • 接 CDN 要做哪几步,源站要不要改?
  • CDN 的缓存规则怎么设计,忽略查询串有什么风险?
  • 接上 CDN 后日志里全是 CDN 节点 IP,风控和统计全乱了?
  • CDN 侧证书和源站证书是什么关系?
  • HTTP/2、HTTP/3 该不该开,条件是什么?
  • 回源费用怎么控?

是否需要 CDN

场景是否需要原因
用户跨省甚至跨国,静态资源多(图片/JS/CSS/下载)需要就近分发,首屏与下载速度提升最明显
营销活动、短视频、直播等流量峰值明显需要边缘吸收峰值,源站不至于被打挂
有 DDoS/CC 风险,需要清洗与隐藏源站 IP需要CDN 同时承担防护与 IP 隐藏
纯动态接口站(后台系统、API 服务)基本不需要动态请求无法缓存,回源比例接近 100%
个人工具站、用户主要在一个区域、日 PV 几千通常不需要一台 1~2 核机器 + 合理缓存就够,CDN 反而增加排查成本
源站带宽与费用已是瓶颈需要,但要算账回源流量、请求数、刷新次数都可能计费

「CDN 不是万能」:它不会让你的慢 SQL 变快,也不会让计算密集的接口变快;它只解决「静态内容离用户远」和「流量峰值」两个问题。接入前先问一句:我的瓶颈真的是分发距离吗?

接入流程与源站配置

① 在 CDN 控制台添加加速域名(需要该域名已 ICP 备案,国内节点必须)
② DNS 处把加速域名 CNAME 到 CDN 分配的地址(不要用 A 记录指源站 IP)
③ 配置回源:回源地址(IP 或域名)、回源端口、回源协议(HTTPS 优先)、回源 Host
④ 配置缓存规则、HTTPS 证书、强制 HTTPS 跳转、HTTP/2 与 HTTP/3 开关
⑤ 源站侧:只允许 CDN 回源网段访问,并还原真实客户端 IP
⑥ 验证:curl 看响应头是否出现 CDN 节点标识,再对比源站直连的差异
# 源站:还原真实 IP(限流、日志、风控的前提),网段以 CDN 厂商文档为准
set_real_ip_from 100.64.0.0/10;
real_ip_header   X-Forwarded-For;
real_ip_recursive on;

server {
    listen 443 ssl;
    server_name static.example.com;

    # 回源鉴权:CDN 配置固定请求头,源站不认就 403
    # 更稳的做法是安全组/防火墙只放行 CDN 回源网段,双保险更好
    if ($http_x_cdn_token != "replace-with-your-token") { return 403; }

    location / { root /srv/www/site; expires 30d; }
    location /api/ {
        proxy_pass http://app_backend;
        add_header Cache-Control "no-store" always;   # 动态接口明确告诉 CDN 不要缓存
    }
}

缓存规则设计

资源路径/后缀边缘缓存时间忽略查询串说明
带哈希的静态资源*.js *.css *.woff230 天 ~ 1 年可以忽略文件名变即新资源
图片/img/*7 ~ 30 天不可忽略同一路径常靠参数区分尺寸/裁剪
HTML/*.html不缓存,或 1~5 分钟不忽略长缓存会导致发布不生效
接口/api/*不缓存不忽略除显式声明的公开只读接口
robots / sitemap/robots.txt/sitemap.xml1 小时不忽略一天一次抓取足够
下载/安装包/download/*7 天不忽略大文件最值得上 CDN

「忽略查询串」是 CDN 配置里最容易出事的一项:一旦忽略,/img/a.jpg?w=200/img/a.jpg?w=800 会被当成同一个资源,先到哪个就把哪个缓存住,用户看到错尺寸甚至错内容的图片。默认一律不忽略,只有明确由文件名区分内容的资源才忽略。

刷新与预热:刷新(清除边缘缓存)有配额限制且生效需几分钟,发版时只刷 HTML,静态资源靠文件名哈希自然更新。预热是在活动或发布前把热门 URL 主动拉到边缘,避免流量瞬间全部回源造成雪崩——大促前值得做,日常小站意义不大。

HTTPS 与真实 IP

CDN 上其实有两段 TLS:用户 ↔ CDN 节点(用 CDN 侧配置的证书)和 CDN 节点 ↔ 源站(用源站证书或厂商托管证书)。两者互相独立,所以:

情况结果
CDN 侧有证书、源站没有用户看到安全锁,但 CDN 到源站是明文 http,仍有被抓包风险
CDN 侧有证书、源站证书过期回源失败,用户看到 502/521 一类错误,且容易误判成 CDN 问题
两边都开「强制 HTTPS 跳转」可能形成跳转循环,只在一侧跳转即可

真实 IP 的取法:CDN 回源时把用户 IP 放在 X-Forwarded-For,源站用 set_real_ip_from + real_ip_header 还原(见上面配置)。不还原的后果是日志统计、Nginx 限流、应用风控全部按 CDN 节点 IP 计算——要么所有用户互相误伤,要么一个都限不住。

HTTP/2 与 HTTP/3 现状

特性生效位置开启条件说明
HTTP/2用户 ↔ CDN(默认开);也可在源站开必须基于 HTTPS;源站 Nginx 需 1.9.5+多路复用、头部压缩,解决应用层队头阻塞(TCP 层仍在)
HTTP/3 (QUIC)一般只在 CDN 侧开CDN 开关 + 客户端支持 + UDP 443 放行基于 UDP,弱网与移动网络提升明显;源站自行开启意义有限
Alt-Svc 头CDN 自动下发自动告诉浏览器「这个站也支持 h3」,浏览器后续才会尝试

源站自己在 Nginx 上开 HTTP/2 的写法(1.25.1+):

server {
    listen 443 ssl;
    http2 on;                          # 旧版写 listen 443 ssl http2;
    ssl_certificate     /etc/nginx/certs/example.com.fullchain.pem;
    ssl_certificate_key /etc/nginx/certs/example.com.key;
}

验证:curl -sI --http2 https://example.com/ 的响应行应显示 HTTP/2。HTTP/3 在命令行验证不方便,用浏览器 DevTools 的 Protocol 列看 h3 更直接。

回源费用控制要点:回源流量按 GB 计费、请求数也可能计费,所以命中率就是钱——把能缓存的都配上缓存、避免忽略查询串造成缓存碎片、发版不要刷全站静态资源、大文件(视频/安装包)改用对象存储 + CDN 而不是从应用服务器回源。

验证方法

# 1) 是否真的走了 CDN:看响应头里的节点标识(不同厂商头名不同)
curl -sI https://static.example.com/ | grep -i -E 'via|x-cache|server|age'
# 2) 连续请求两次,看 Age 是否增长(增长说明命中边缘缓存)
curl -sI https://static.example.com/img/logo.png | grep -i age
# 3) 绕过 CDN 直连源站对比(--resolve 强制解析到源站 IP)
curl -sI --resolve static.example.com:443:47.98.x.x https://static.example.com/ | head -3
# 4) 源站日志里是否是真实用户 IP(配了 real_ip 之后)
tail -5 /var/log/nginx/access.log
# 5) 缓存头是否符合预期
curl -sI https://static.example.com/assets/app.a1b2c3.js | grep -i cache-control

常见坑

现象做法
忽略查询串图片尺寸/内容错乱默认不忽略
HTML 被边缘长缓存发布后用户仍是旧页面HTML 不缓存,只刷 HTML
源站没还原真实 IP限流误伤、日志全是 CDN 节点set_real_ip_from + real_ip_header
源站仍然对全网开放有人直接打源站 IP 绕过 CDN 与防护安全组只放行 CDN 回源网段 + 回源鉴权
两侧都开强制跳转跳转循环、请求异常只在一侧配置
以为开了 CDN 接口就快了动态接口没有任何改善优化 SQL/缓存,CDN 帮不上
没算回源费用账单远超预期提升命中率、大文件走对象存储
源站证书过期CDN 回源失败,误判为 CDN 故障把源站证书纳入到期监控

小结:CDN 只解决「静态内容离用户远」和「流量峰值」两件事,接入前先确认瓶颈真在这;接入的关键动作是「CNAME 接入 → 源站只放行回源网段并还原真实 IP → 按资源类型设计缓存规则 → 只刷 HTML 不刷静态资源」;查询串默认不要忽略,HTTPS 要弄清楚用户侧与回源侧是两套证书;HTTP/2 源站可开、HTTP/3 交给 CDN;最后再强调一次——动态接口密集、用户集中的小站,把缓存头和压缩配好,比接 CDN 更有效。

笔记加载中…