2026-09-09 09:44AM
给网站增加 CDN 全球加速,从源站配置到全球访问优化的完整实践
最近给自己的网站增加了 CDN 全球加速。
网站前端使用 React,后端使用 Go,源站部署在中国大陆。由于网站的用户可能来自美国、日本、新加坡、欧洲等海外地区,如果所有静态资源都直接从中国大陆源站加载,海外用户访问时容易出现明显的延迟。
最开始的网站结构比较简单:
用户
↓
中国大陆服务器
↓
Nginx
↓
React 前端
+
Go 后端
这种架构在中国大陆访问没有太大问题。
但是,如果用户在美国、日本、欧洲等地区:
海外用户
↓
跨境网络
↓
中国大陆源站
↓
返回 JS/CSS/图片等静态资源
所有资源都需要从中国大陆服务器传输到海外。
尤其是 React 网站,一个页面可能需要加载:
index.html
xxx.js
xxx.css
字体
图片
其他静态资源
如果 JS 文件比较大,就会明显影响首次打开速度。
因此需要把静态资源放到离用户更近的 CDN 节点。
CDN 的核心思想并不复杂:
把源站上的静态资源缓存到全球各地的 CDN 节点。
eg:我的源站位于中国大陆。
没有 CDN:
美国用户
↓
中国大陆源站
↓
JS
使用 CDN:
美国用户
↓
美国/附近 CDN 节点
↓
JS
第一次访问时,如果 CDN 没有资源:
用户
↓
CDN 节点
↓
源站
↓
CDN 缓存
↓
用户
之后其他用户再次请求:
用户
↓
CDN 节点
↓
直接返回缓存
这样就减少了跨境回源。
这里是配置 CDN 时非常重要的一点。
我的网站实际上包含三类资源:
3.1. 前端静态资源
例如:
.js
.css
.png
.jpg
.jpeg
.webp
.gif
.ico
.woff
.woff2
这些资源非常适合 CDN。
3.2. HTML
例如:
index.html
HTML 和 JS/CSS 不太一样。
如果把 HTML 设置成非常长时间缓存,那么网站发布新版本之后,用户可能仍然拿到旧 HTML。
所以通常:
HTML
↓
短缓存 / 不缓存
而:
JS
CSS
字体
图片
↓
长期缓存
3.3. API
我的 API 域名是:
api.mysite.com
里面主要是 Go 后端接口,例如:
创建任务
查询任务
用户信息
积分
支付
视频生成状态
这些都是动态请求。
因此不应该简单地把 API 响应缓存到 CDN。
最终采用:
mysite.com
↓
CDN
而:
api.mysite.com
↓
直接访问 API 源站
这样更加合理。

API方面:
用户
↓
api.mysite.com
↓
Go API 源站
↓
动态请求,不做 CDN 缓存
视频:
用户
↓
OSS 全球加速
↓
MP4 视频文件
这篇文章记录整个配置过程。
在阿里云 CDN 中创建加速域名。
例如:
mysite.com
或者根据自己的实际域名配置。
配置时需要指定:
加速域名
源站类型
源站地址
源站 HOST
HTTPS
缓存规则
这里最重要的是:
CDN 必须知道自己的源站在哪里。
例如:
CDN
↓
mysite.com 源站服务器
假设源站服务器是:
中国大陆服务器
网站通过 Nginx 提供 HTTPS:443
Nginx 类似:
server {
listen 443 ssl;
server_name mysite.com www.mysite.com;
ssl_certificate xxx.pem;
ssl_certificate_key xxx.key;
...
}
这里需要保证:
CDN → 源站
这一段能够正常通信。
也就是说,不能只考虑:
用户 → CDN
还必须考虑:
CDN → 源站
否则 CDN 虽然创建成功,但是回源的时候仍然可能出现:
502 Bad Gateway
这是后来排查问题时非常重要的一项。
CDN 回源时,需要告诉源站:
Host: mysite.com
因此可以配置:
Default Origin HOST:开启
Custom Origin Host:
mysite.com
为什么需要这个配置?
因为 Nginx 经常根据:
Host
来匹配:
server_name
例如:
server_name mysite.com www.mysite.com;
如果 CDN 回源的时候 Host 不正确,Nginx 可能匹配不到正确的 Server。
因此:
CDN
↓
Host: mysite.com
↓
Nginx
↓
server_name mysite.com
这一链路必须保持一致。
我的网站本身使用 HTTPS:
https://mysite.com
因此 CDN 也需要配置 HTTPS。
基本思路:
用户
↓ HTTPS
CDN
↓ HTTPS
源站
而不是:
用户
↓ HTTPS
CDN
↓ HTTP
源站
当然,CDN → 源站是否使用 HTTPS,要根据实际安全要求和源站配置决定。
如果源站本身监听:443
并且已经配置 SSL,那么可以让 CDN 使用 HTTPS 回源。
例如:
HTTPS Port: 443
Protocol: Follow Origin
HTTPS 回源的时候,如果一个 IP 上存在多个 HTTPS 网站,就涉及 SNI。
例如:
服务器 IP
├── mysite.com
├── example.com
└── other.com
CDN 回源时需要明确告诉服务器:
我要访问的是 mysite.com
因此可以配置:
SNI:开启
SNI:
mysite.com
这样 CDN → 源站进行 TLS 握手时,可以携带正确的域名。
这是整个 CDN 配置中最重要的一步之一。
我给网站设置的核心思路是:
HTML
↓
不长期缓存
JS
↓
长期缓存
CSS
↓
长期缓存
图片
↓
长期缓存
字体
↓
长期缓存
MP4
↓
根据实际存储方式处理
例如:
css
js
mp4
jpg
jpeg
png
webp
gif
ico
woff
woff2
可以设置比较长的缓存时间。
例如 React 项目经常会生成:
assets/index-8a7f23.js
assets/index-91c2ab.css
这种文件名带 hash 的静态资源非常适合长期缓存。
因为代码更新之后:
index-8a7f23.js
会变成:
index-c91d821.js
新旧文件名不同,因此可以安全地设置:
Cache-Control: max-age=31536000, immutable
也就是大约一年。
例如:
index.html
如果设置:
max-age=31536000
那么用户可能长时间拿不到最新 HTML。
因此更合理的是:
index.html
↓
no-cache
或者设置较短的缓存时间(eg:一个月)。
这样用户访问:
mysite.com
时,可以更及时获得最新版本。
而 HTML 引用的:
xxx.js
xxx.css
仍然可以从 CDN 高速获取。
CDN 配置完成以后,并不是马上所有用户都会经过 CDN。
还需要修改 DNS。
原来的结构可能是:
mysite.com
↓
A
↓
源站 IP
配置 CDN 后,需要变成:
mysite.com
↓
CNAME
↓
CDN 加速域名
↓
CDN 节点
↓
源站
也就是说:
用户
↓
DNS
↓
CDN
而不是:
用户
↓
DNS
↓
源站 IP
当时某个 DNS CNAME 配置启用后:
Chrome
↓
502 Bad Gateway
但是:
Chrome 无痕模式
↓
正常
Firefox:
正常
后来排查发现,问题和 DNS/CDN 配置有关。
因此配置 CDN 后,如果出现:
502
不要马上认为是 CDN 本身坏了。
需要分别检查:
DNS
↓
CDN
↓
CDN 回源
↓
Nginx
↓
HTTPS
↓
应用
可以按照这个顺序排查。
14.1. 先确认源站是否正常
直接访问源站。
例如:
curl -I https://mysite.com
如果源站本身就是:
HTTP/2 200
说明源站基本正常。
14.2. 检查 Nginx
确认:
443
是否监听。
例如:
ss -lntp | grep 443
同时检查:
server_name
ssl_certificate
ssl_certificate_key
14.3 检查防火墙
确保 CDN 节点能够访问源站:
TCP 443
不能只保证自己的电脑可以访问
14.4 检查 Origin Host
确认:
Host: mysite.com
和 Nginx:
server_name mysite.com;
能够对应。
14.5 检查 SNI
HTTPS 回源出现问题时,检查:
SNI
是否开启,并确认:
SNI = mysite.com
14.6 使用 curl 测试
例如:
curl -I https://mysite.com
也可以使用:
curl -v https://mysite.com
查看:
DNS
TCP
TLS
HTTP
整个过程。
这是非常重要的一步。
不能仅仅看到:
HTTP 200
就认为 CDN 已经生效。
因为:
源站 200
和:
CDN 200
是两回事。
需要查看 HTTP 响应头。
例如后来测试 JS 文件时,看到类似:
server: Tengine
content-type: application/javascript
cache-control: max-age=31536000 public, max-age=31536000, immutable
age: 88
x-cache: HIT
TCP_MEM_HIT
其中非常关键的是:
x-cache: HIT
以及:
TCP_MEM_HIT
这说明:
CDN 节点已经命中缓存,并直接从 CDN 返回资源。
也就是说:
用户
↓
CDN
↓
缓存中的 JS
而不是:
用户
↓
CDN
↓
源站
↓
JS
刚配置 CDN 时,第一次访问一个资源:
用户
↓
CDN
↓
发现没有缓存
↓
源站
↓
返回资源
↓
CDN 缓存
↓
用户
这时候可能看到:
x-cache: MISS
第二次:
用户
↓
CDN
↓
缓存
↓
用户
可能变成:
x-cache: HIT
所以:
MISS
并不意味着 CDN 配置失败。
我的网站后来测试 HTML 时出现过:
x-cache: MISS
TCP_MISS
同时 HTML 设置了:
Cache-Control: no-cache
这种情况下 CDN 不长期缓存 HTML 是符合预期的。
真正需要重点关注的是:
JS
CSS
图片
字体
视频
这些静态资源是否能够:
HIT
我的网站还有大量 AI 视频生成后的 MP4。
这类文件不建议简单地和普通 HTML 一样处理。
我的视频文件放在:
Alibaba Cloud OSS
并且 OSS 已经配置了全球域名加速。
因此采用:
用户
↓
OSS 全球加速
↓
MP4
而网站静态资源:
用户
↓
CDN
↓
JS/CSS/图片/字体
这样可以把:
网站静态资源
和:
大文件视频
分别进行优化。
最后不能只在自己的电脑上测试(可以在阿里云的无影云上面进行测试,需要付费)
因为 CDN 的核心目的就是:改善全球不同地区用户访问网站的速度
因此应该测试:
中国大陆
香港
日本
新加坡
韩国
美国
加拿大
英国
德国
法国
澳大利亚
重点观察:
DNS
TCP
TLS
TTFB
页面加载时间
JS 下载时间
CSS 下载时间
尤其是:
TTFB
和:
页面完全加载时间
可以比较:
CDN 前
VS
CDN 后
这样才能真正判断 CDN 是否有效。
给网站增加 CDN,并不是简单地:
购买 CDN
↓
修改 DNS
↓
结束
完整流程应该是:
① 分析网站架构
↓
② 区分静态资源和动态 API
↓
③ 创建 CDN 加速域名
↓
④ 配置源站
↓
⑤ 配置 Origin Host
↓
⑥ 配置 HTTPS
↓
⑦ 配置 SNI
↓
⑧ 配置缓存规则
↓
⑨ 配置 DNS CNAME
↓
⑩ 等待 DNS 生效
↓
⑪ 测试 CDN 是否正常回源
↓
⑫ 检查 HTTP 响应头
↓
⑬ 确认 x-cache HIT
↓
⑭ 全球不同地区测速
↓
⑮ 根据测试结果继续优化
对于我的 mysite.com 来说,最终采用的是:
┌───────────────────┐
│ mysite.com │
│ │
│ React 前端 │
│ JS / CSS / 图片 / 字体 │
│ ↓ │
│ 阿里云 CDN │
│ ↓ │
│ 全球 CDN 节点 │
└───────────────────┘
┌───────────────────┐
│ api.mysite.com │
│ │
│ Go API │
│ ↓ │
│ 直接源站 │
│ │
│ CDN 不缓存动态 API │
└───────────────────┘
┌───────────────────┐
│ MP4 视频 │
│ │
│ OSS │
│ ↓ │
│ 全球加速 │
└───────────────────┘
这样做的核心目的不是“让所有请求都经过 CDN”,而是:
让最适合缓存的静态资源尽可能在距离用户更近的 CDN 节点提供,同时让动态 API 保持正常的实时请求,让大体积视频通过 OSS 全球加速传输。
登录
请登录后再发表评论。
评论列表:
目前还没有人发表评论