mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4
4136 字
11 分钟
CDN与内容分发:数据包的捷径
2022-08-30

HTTP协议演进 中,看到 HTTP/2 和 HTTP/3 通过多路复用、头部压缩、0-RTT 等机制不断压缩协议层面的开销。但无论协议多精巧,物理距离的延迟无法消除——光速限制下,北京到纽约的往返至少需要 130ms。如果每个请求都要跨越半个地球去源站获取数据,再精巧的协议也救不了用户体验。

CDN(Content Delivery Network)的思路很简单:把数据搬到离用户更近的地方。用户请求不再穿越半个地球去源站,而是被路由到最近的边缘节点,从本地缓存获取内容。这不仅是延迟的优化,更是可靠性、带宽成本和安全防护的系统性解决方案。

本章从 CDN 的设计动机出发,深入任播路由与 PoP 分布的架构原理,解析缓存策略与回源机制的工程细节,探讨动态加速和安全防护的实现方式,最后通过动手实验观察 CDN 的真实行为。下一章 数据中心与SDN网络 将走进 CDN 节点背后的数据中心,看 CLOS 架构和 SDN 如何支撑海量请求的转发。

一、为什么需要CDN#

1.1 源站远在天边#

互联网的核心设计原则是端到端——数据包从源到宿,中间经过多少跳路由器、穿越多少个 AS,全凭 BGP与域间路由 的策略决定。一个部署在美东的源站,服务亚太用户时,数据包要穿越太平洋海底光缆,经过多个 IXP与互联网交换 点,跳过十几个路由器。

以北京用户访问美东源站为例:

  • 物理距离约 11000km,光速限制下单程约 37ms,往返 74ms
  • 加上路由器处理、排队、拥塞控制等开销,实际 RTT 通常 150-300ms
  • TCP流控与拥塞控制 的慢启动机制意味着前几个 RTT 内带宽利用率极低
  • 一次完整的页面加载涉及数十个请求,串行依赖下延迟不断叠加

1.2 单点故障与带宽瓶颈#

源站集中部署带来三个工程问题:

单点故障:源站所在机房断电、光纤被挖断、上游路由故障——所有用户同时无法访问。2017 年 Amazon S3 us-east-1 区域故障,导致大量依赖 S3 的网站和服务瘫痪数小时。

带宽瓶颈:热门内容突发流量时,源站出口带宽成为瓶颈。一个 10Gbps 的源站出口,面对全球用户的同时请求,分到每个用户的带宽可能只有几十 Kbps。

成本压力:跨运营商、跨大洲的流量费用远高于本地流量。源站在美东,亚太用户的流量要穿越太平洋,带宽成本是本地流量的 5-10 倍。

1.3 CDN的核心思路#

CDN 用”空间换时间”的策略解决上述问题:

问题CDN 策略效果
物理距离远边缘节点就近响应RTT 从 200ms 降到 10-30ms
单点故障多节点冗余单节点故障不影响全局
带宽瓶颈流量分散到边缘源站带宽需求降低 90%+
流量成本本地出口跨洲流量减少 80%+

二、CDN架构与任播路由#

2.1 CDN整体架构#

CDN 由分布在全球的 PoP(Point of Presence)节点、调度系统和源站组成:

graph TB subgraph 用户侧[" 用户"] U1["北京用户"] U2["东京用户"] U3["纽约用户"] end subgraph DNS调度[" DNS 调度"] DNS["权威 DNS<br/>CNAME → CDN DNS"] CDNS["CDN 全局负载均衡<br/>GSLB"] end subgraph PoP节点[" 边缘节点 PoP"] POP1["北京 PoP<br/>缓存 + 安全"] POP2["东京 PoP<br/>缓存 + 安全"] POP3["纽约 PoP<br/>缓存 + 安全"] end subgraph 源站[" 源站 Origin"] ORIGIN["origin.example.com<br/>原始内容"] end U1 -->|"1. DNS 查询"| DNS U2 -->|"1. DNS 查询"| DNS U3 -->|"1. DNS 查询"| DNS DNS -->|"2. CNAME 指向"| CDNS CDNS -->|"3. 返回最近 PoP IP"| U1 CDNS -->|"3. 返回最近 PoP IP"| U2 CDNS -->|"3. 返回最近 PoP IP"| U3 U1 -->|"4. 请求"| POP1 U2 -->|"4. 请求"| POP2 U3 -->|"4. 请求"| POP3 POP1 -->|"5. 未命中回源"| ORIGIN POP2 -->|"5. 未命中回源"| ORIGIN POP3 -->|"命中缓存"| U3 style 用户侧 fill:#e3f2fd,stroke:#1565c0 style DNS调度 fill:#fff3e0,stroke:#e65100 style PoP节点 fill:#e8f5e9,stroke:#2e7d32 style 源站 fill:#fce4ec,stroke:#880e4f

用户访问 CDN 资源的典型流程:

  1. 用户请求 cdn.example.com,本地 DNS 递归查询
  2. 权威 DNS 返回 CNAME,指向 CDN 的全局负载均衡(GSLB)域名
  3. GSLB 根据用户 IP、节点负载、网络状况返回最优 PoP 的 IP
  4. 用户向 PoP 发起 HTTP 请求
  5. PoP 缓存命中则直接返回;未命中则回源获取并缓存

2.2 任播:同一个IP,多个位置#

CDN 能让用户”自动”找到最近节点,核心机制是任播(Anycast)。与单播(Unicast)一个 IP 对应一台主机不同,任播让同一个 IP 地址在多个地理位置同时宣告。

graph TB subgraph 任播网络[" 任播路由 203.0.113.100"] R1["路由器 R1<br/>AS 64510"] R2["路由器 R2<br/>AS 64520"] R3["路由器 R3<br/>AS 64530"] end subgraph PoP节点["PoP 节点(同一 IP)"] P1["北京 PoP<br/>203.0.113.100"] P2["东京 PoP<br/>203.0.113.100"] P3["纽约 PoP<br/>203.0.113.100"] end subgraph BGP宣告["BGP 路由宣告"] P1 -->|"BGP: 203.0.113.100/32<br/>via AS64510"| R1 P2 -->|"BGP: 203.0.113.100/32<br/>via AS64520"| R2 P3 -->|"BGP: 203.0.113.100/32<br/>via AS64530"| R3 end subgraph 用户请求["用户请求"] U1["北京用户"] -->|"BGP 选路 → AS64510"| P1 U2["东京用户"] -->|"BGP 选路 → AS64520"| P2 U3["纽约用户"] -->|"BGP 选路 → AS64530"| P3 end style 任播网络 fill:#e8eaf6,stroke:#283593 style PoP节点 fill:#e8f5e9,stroke:#2e7d32 style BGP宣告 fill:#fff3e0,stroke:#e65100 style 用户请求 fill:#fce4ec,stroke:#880e4f

任播的工作原理依赖 BGP与域间路由 的选路机制:

  • 每个 PoP 节点通过 BGP 向上游路由器宣告相同的 IP 前缀
  • BGP 路由器根据 AS_PATH 长度、策略等属性选择”最优”路径
  • 用户的数据包自然被路由到 BGP 意义上”最近”的 PoP
  • 无需 DNS 精确调度,网络层自动完成就近接入
Note

任播的”最近”是 BGP 路由意义上的最近,不一定是物理距离最近。BGP 选路受策略、商业关系影响,可能出现物理距离近但 BGP 路径远的情况。因此大型 CDN 通常结合 DNS 调度(GSLB)和任播两种方式——DNS 层面做粗粒度调度,任播做细粒度优化。

2.3 DNS调度 vs 任播#

维度DNS 调度(GSLB)BGP 任播
调度粒度基于 DNS 解析 IP 粗粒度地域基于 BGP 路由细粒度就近
响应速度DNS 缓存 TTL 延迟(分钟级)BGP 收敛秒级
负载均衡可感知节点负载动态调整依赖 BGP 自然分布,可能不均
故障转移DNS TTL 过期后才能切换BGP 撤回路由立即生效
精确度受 DNS 递归服务器位置影响受 BGP 策略影响
典型用途HTTP/HTTPS 流量调度DNS 服务、DDoS 防护流量稀释

实际部署中,两种方式通常组合使用:DNS 调度将用户引导到合适的区域集群,任播在集群内做就近接入和故障切换。

2.4 PoP节点的内部结构#

一个典型的 PoP 节点包含以下组件:

  • 边缘路由器:BGP 任播宣告,接收用户流量
  • L4 负载均衡:基于 IP+端口做四层分发,通常用 LVS 或等效方案
  • L7 代理/缓存:Nginx、Varnish 或自研缓存引擎,处理 HTTP 请求
  • SSL 卸载:TLS 终止,将解密后的请求转发给缓存层
  • 回源模块:缓存未命中时向源站请求内容
  • 日志与监控:访问日志、缓存命中率、回源延迟等指标采集

三、缓存策略#

3.1 缓存键与Vary#

CDN 缓存的核心问题是:什么决定一个资源是否命中缓存? 答案是缓存键(Cache Key)。

缓存键通常由以下部分组成:

  • 请求 URL(含查询参数)
  • Vary 头指定的请求头

Vary 头告诉 CDN:对于同一个 URL,不同的请求头值对应不同的缓存版本。最常见的例子是内容压缩:

# Nginx 缓存配置示例
proxy_cache_path /var/cache/cdn levels=1:2 keys_zone=cdn_cache:100m
max_size=50g inactive=60m use_temp_path=off;
server {
listen 443 ssl;
server_name cdn.example.com;
# 缓存键默认是 $scheme$proxy_host$request_uri
# Vary: Accept-Encoding 时,gzip 和 br 版本分别缓存
proxy_cache_key $scheme$proxy_host$request_uri$http_accept_encoding;
location /assets/ {
proxy_cache cdn_cache;
# 缓存有效期
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
# 启用陈旧缓存
proxy_cache_use_stale error timeout updating;
proxy_cache_background_update on;
# 添加缓存状态头
add_header X-Cache-Status $upstream_cache_status;
proxy_pass http://origin;
}
}
Warning

Vary 头使用不当会导致缓存命中率暴跌。Vary: * 等价于禁止缓存;Vary: User-Agent 会因为 UA 字符串的多样性产生大量缓存副本,浪费存储空间。实践中应只对真正影响响应内容的请求头做 Vary。

3.2 Cache-Control详解#

HTTP协议演进 中介绍了 Cache-Control 的基本语义,这里从 CDN 角度深入:

指令含义CDN 行为
max-age=3600缓存 3600 秒在有效期内直接返回,不回源
s-maxage=600共享缓存有效期 600 秒CDN 遵循此值而非 max-age
no-cache每次使用前必须验证CDN 发送条件请求(304 验证)
no-store不缓存任何内容CDN 不存储响应
public允许共享缓存缓存即使有 Authorization 头也可缓存
private仅浏览器可缓存CDN 不缓存
stale-while-revalidate=60允许 60 秒内返回陈旧内容后台异步刷新,用户无感知
stale-if-error=300错误时允许返回 300 秒内的陈旧内容源站故障时的容错

stale-while-revalidate 是 CDN 场景下特别重要的指令——它让 CDN 在缓存过期时先返回陈旧内容给用户,同时在后台异步回源刷新。用户感知到的延迟始终是缓存命中的延迟,不会因为回源而阻塞。

3.3 缓存决策流程#

CDN 收到请求后,缓存决策的完整流程:

flowchart TB REQ["收到请求"] --> KEY["计算缓存键<br/>URL + Vary 头"] KEY --> LOOKUP["查找缓存"] LOOKUP -->|"命中"| FRESH{"缓存是否新鲜?"} LOOKUP -->|"未命中"| MISS["Cache MISS<br/>回源获取"] FRESH -->|"新鲜"| HIT["Cache HIT<br/>直接返回"] FRESH -->|"过期"| SWR{"stale-while-revalidate?"} SWR -->|"支持"| STALE["返回陈旧内容<br/>后台异步回源刷新"] SWR -->|"不支持"| REVAL["发送条件请求<br/>If-None-Match / If-Modified-Since"] REVAL -->|"304 Not Modified"| REFRESH["刷新缓存有效期<br/>返回缓存内容"] REVAL -->|"200 OK"| UPDATE["更新缓存<br/>返回新内容"] MISS --> STORE["存储到缓存<br/>返回给用户"] HIT --> LOG["记录 HIT 指标"] STALE --> LOG REFRESH --> LOG UPDATE --> LOG STORE --> LOG style REQ fill:#e3f2fd,stroke:#1565c0 style HIT fill:#c8e6c9,stroke:#2e7d32 style MISS fill:#ffcdd2,stroke:#c62828 style STALE fill:#fff9c4,stroke:#f9a825

3.4 缓存清除与失效#

CDN 缓存失效有三种方式:

自然过期:等待 max-age / s-maxage 到期,最简单但不够及时。

主动清除(Purge):通过 API 或管理界面强制清除指定 URL 的缓存:

# Cloudflare 缓存清除 API
curl -X POST "https://api.cloudflare.com/client/v4/zones/{zone_id}/purge_cache" \
-H "Authorization: Bearer {api_token}" \
-H "Content-Type: application/json" \
-d '{
"files": [
"https://cdn.example.com/css/style.css",
"https://cdn.example.com/js/app.js"
]
}'
# 清除所有缓存
curl -X POST "https://api.cloudflare.com/client/v4/zones/{zone_id}/purge_cache" \
-H "Authorization: Bearer {api_token}" \
-H "Content-Type: application/json" \
-d '{"purge_everything": true}'

缓存键版本化:在 URL 中嵌入版本号或哈希值(如 app.v2a3f5.js),更新时发布新文件名而非覆盖旧文件。这是最可靠的方案——旧版本自然过期,新版本立即生效。

3.5 缓存命中率指标#

指标含义典型值
HIT缓存命中,直接返回85-95%
MISS缓存未命中,回源获取3-8%
EXPIRED缓存过期,需验证2-5%
STALE返回陈旧内容,后台刷新<1%
BYPASS请求绕过缓存(如 no-store)<1%

缓存命中率是 CDN 最核心的运营指标。90% 以上的命中率意味着 90% 的请求不需要回源,源站带宽和负载大幅降低。

四、回源与动态加速#

4.1 回源机制#

当 PoP 缓存未命中时,需要向源站请求内容,这个过程叫回源(Origin Pull)。回源的效率直接影响用户感知延迟和源站负载。

Varnish VCL 中回源逻辑的典型配置:

# Varnish VCL 回源配置
vcl 4.1;
backend origin {
.host = "origin.example.com";
.port = "443";
.ssl = 1;
.probe = {
.url = "/health";
.interval = 5s;
.timeout = 2s;
.window = 5;
.threshold = 3;
}
}
sub vcl_recv {
# 不缓存的路径直接回源
if (req.url ~ "^/api/") {
return (pass);
}
# 规范化 Accept-Encoding,减少缓存分片
if (req.http.Accept-Encoding) {
if (req.http.Accept-Encoding ~ "br") {
set req.http.Accept-Encoding = "br";
} elsif (req.http.Accept-Encoding ~ "gzip") {
set req.http.Accept-Encoding = "gzip";
} else {
unset req.http.Accept-Encoding;
}
}
}
sub vcl_backend_response {
# 遵循源站 Cache-Control,但覆盖 s-maxage
if (beresp.http.Cache-Control ~ "s-maxage") {
# 使用源站指定的共享缓存时间
} elsif (beresp.status == 200) {
# 默认缓存 10 分钟
set beresp.ttl = 10m;
set beresp.grace = 1h; # 陈旧容错窗口
}
# 不缓存私有内容
if (beresp.http.Cache-Control ~ "private") {
set beresp.uncacheable = true;
}
}

4.2 回源优化#

CDN 在回源链路上做了大量优化,减少源站压力和回源延迟:

连接复用:PoP 与源站之间保持长连接池,避免每次回源都经历 TCP连接管理 的三次握手开销。

回源合并(Request Coalescing):多个用户同时请求同一个未缓存资源时,PoP 只发送一次回源请求,其余请求等待结果。这避免了”惊群效应”——热门资源过期瞬间大量回源请求涌向源站。

源站屏蔽(Origin Shield):在 PoP 和源站之间增加一层屏蔽层,所有回源请求先经过屏蔽节点。屏蔽节点缓存命中则直接返回,避免多个 PoP 重复回源。

4.3 动态内容加速#

静态资源(图片、CSS、JS)天然适合缓存,但动态内容(API 响应、个性化页面)无法缓存。CDN 对动态内容的加速依赖网络层优化:

优化手段原理效果
TCP 参数调优增大初始拥塞窗口、启用窗口缩放减少慢启动耗时
路由优化选择延迟最低的回源路径避免绕行
连接预建预先建立到源站的 TCP/TLS 连接消除握手延迟
压缩传输在 PoP 和源站间启用高压缩比减少传输数据量
TLS 优化会话复用、OCSP 装订减少 TLS 开销

4.4 静态加速 vs 动态加速#

维度静态加速动态加速
核心手段边缘缓存网络路径优化
缓存策略长 TTL、stale-while-revalidateno-cache 或短 TTL
回源频率低(命中率 >90%)高(每次请求都回源)
延迟改善显著(200ms → 20ms)中等(200ms → 120ms)
典型内容图片、CSS、JS、视频API、个性化页面、实时数据
带宽节省极大有限
适用场景内容分发连接加速

五、CDN安全#

5.1 DDoS防护:在边缘稀释流量#

CDN 的分布式架构天然适合 DDoS 防护——攻击流量被分散到全球数百个 PoP 节点,每个节点只需承受总攻击流量的一小部分。这就是”流量稀释”效应。

flowchart LR subgraph 攻击流量[" 攻击流量 100Gbps"] A1["僵尸网络 A<br/>30Gbps"] A2["僵尸网络 B<br/>40Gbps"] A3["僵尸网络 C<br/>30Gbps"] end subgraph CDN边缘[" CDN 边缘节点"] P1["PoP-1<br/>承受 15Gbps<br/>可承受"] P2["PoP-2<br/>承受 20Gbps<br/>可承受"] P3["PoP-3<br/>承受 15Gbps<br/>可承受"] P4["PoP-4<br/>承受 25Gbps<br/>可承受"] P5["PoP-5<br/>承受 25Gbps<br/>可承受"] end subgraph 源站[" 源站"] ORIGIN["origin.example.com<br/>仅承受 2Gbps<br/>正常运行"] end A1 --> P1 A1 --> P2 A2 --> P3 A2 --> P4 A3 --> P4 A3 --> P5 P1 -->|"清洗后正常流量"| ORIGIN P2 -->|"清洗后正常流量"| ORIGIN P3 -->|"清洗后正常流量"| ORIGIN P4 -->|"清洗后正常流量"| ORIGIN P5 -->|"清洗后正常流量"| ORIGIN style 攻击流量 fill:#ffcdd2,stroke:#c62828 style CDN边缘 fill:#e8f5e9,stroke:#2e7d32 style 源站 fill:#e3f2fd,stroke:#1565c0

如果没有 CDN,100Gbps 的攻击流量直接打向源站,源站的 10Gbps 出口瞬间瘫痪。有了 CDN,攻击流量被分散到数百个 PoP,每个 PoP 只承受几百 Mbps,远在其处理能力之内。清洗后的正常流量再回源,源站几乎无感知。

5.2 WAF:应用层防护#

CDN 边缘部署的 WAF(Web Application Firewall)在应用层拦截恶意请求:

  • SQL 注入检测:匹配请求参数中的 SQL 关键字和模式
  • XSS 防护:检测和过滤跨站脚本攻击载荷
  • CC 攻击防护:识别高频访问的 IP,触发速率限制或验证码
  • 虚拟补丁:在官方补丁发布前,通过 WAF 规则临时阻断已知漏洞利用
# Nginx WAF 规则示例(ModSecurity 风格)
SecRuleEngine On
# 阻止 SQL 注入
SecRule ARGS "(?i)(union.*select|insert.*into|delete.*from|drop.*table)" \
"id:1001,phase:2,deny,status:403,msg:'SQL Injection detected'"
# 阻止 XSS
SecRule ARGS "(?i)(<script|javascript:|onerror\s*=|onload\s*=)" \
"id:1002,phase:2,deny,status:403,msg:'XSS attack detected'"
# 速率限制:单 IP 每秒不超过 50 请求
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=50r/s;
limit_req zone=api_limit burst=100 nodelay;

5.3 Bot管理#

CDN 的 Bot 管理区分善意爬虫和恶意机器人:

  • 搜索引擎爬虫:验证 Googlebot/Bingbot 的反向 DNS,放行真爬虫,拦截伪造 UA
  • 自动化攻击:检测请求模式(频率、间隔、行为序列),识别自动化工具
  • 凭据填充:检测大量登录尝试,触发 CAPTCHA 或封禁
  • 爬虫防护:对敏感内容启用 JavaScript 挑战,阻止简单爬虫

5.4 TLS卸载#

CDN 在边缘节点终止 TLS 连接,将解密后的请求转发给内部缓存或回源。这带来两个好处:

性能:TLS 握手在边缘完成,用户到 PoP 的 RTT 更短,握手更快。PoP 到源站的内网链路可以复用长连接,避免重复握手。

证书管理:源站不需要暴露私钥,CDN 统一管理证书的申请、续期和部署。Let’s Encrypt 自动化续期在 CDN 规模下尤其有价值。

5.5 源站屏蔽#

源站屏蔽(Origin Shield / Shield PoP)是安全与性能的双重保障:

  • 所有回源请求经过指定的屏蔽节点,屏蔽节点缓存命中则直接返回
  • 屏蔽节点是回源的唯一出口,源站只需放行屏蔽节点的 IP
  • 攻击者无法直接访问源站 IP,即使 CDN 被绕过,源站仍有保护

六、动手实践:观察CDN行为#

6.1 用curl识别CDN#

# 查看响应头,识别 CDN 特征
curl -I https://www.cloudflare.com
# 典型输出:
# HTTP/2 200
# server: cloudflare
# cf-ray: 8a1b2c3d4e5f6g7h-IAD
# cf-cache-status: HIT
# age: 42
# vary: Accept-Encoding
# 关键字段解读:
# server: cloudflare → CDN 提供商
# cf-ray: 请求追踪 ID + PoP 代码(IAD = 华盛顿杜勒斯)
# cf-cache-status: HIT/MISS/EXPIRED 缓存状态
# age: 缓存已存储的秒数

不同 CDN 提供商的响应头特征:

CDN 提供商特征头PoP 代码位置
Cloudflarecf-raycf-cache-statuscf-ray 后缀(如 -IAD
Akamaix-akamai-transformedx-cachex-cache 值含 PoP 信息
AWS CloudFrontx-amz-cf-idx-cachex-amz-cf-pop
Fastlyx-served-byx-cachex-served-by 含 PoP 代码
阿里云 CDNx-swift-cachetimeali-swift-global-savetimex-swift-sf 含节点信息

6.2 用dig观察CDN的DNS调度#

# 查询 CDN 域名的 DNS 解析链路
dig +trace cdn.example.com
# 第一步:权威 DNS 返回 CNAME
# cdn.example.com. 300 IN CNAME cdn.example.com.cdn.cloudflare.net.
# 第二步:CDN 的 GSLB 返回 PoP IP
# cdn.example.com.cdn.cloudflare.net. 30 IN A 104.16.132.229
# 从不同地理位置查询,对比返回的 IP
# 北京 DNS 服务器查询
dig @223.5.5.5 cdn.example.com
# 返回亚太 PoP 的 IP
# 纽约 DNS 服务器查询
dig @8.8.8.8 cdn.example.com
# 返回美东 PoP 的 IP
# 查看 CNAME 链
dig cdn.example.com CNAME +short
# cdn.example.com.cdn.cloudflare.net.

6.3 用traceroute追踪到PoP#

# 追踪到 CDN 节点的路径
traceroute cdn.example.com
# 观察最后几跳的 IP 和 RTT
# 如果 RTT 在 10-30ms,说明命中了本地 PoP
# 如果 RTT 在 100ms+,可能被路由到了远端 PoP
# 使用 mtr 持续监测
mtr --report cdn.example.com
# 对比直接到源站的路径
traceroute origin.example.com
# 通常 RTT 远大于到 CDN PoP 的 RTT

6.4 Chrome DevTools观察CDN头#

# 用 curl 模拟浏览器请求,观察完整头部
curl -s -D - https://cdn.example.com/image.jpg -o /dev/null
# 输出关键头部:
# HTTP/2 200
# content-type: image/jpeg
# cache-control: public, max-age=86400, s-maxage=3600
# age: 1847
# x-cache: HIT
# x-cache-hits: 42
# via: 1.1 varnish (Varnish/7.3)
# cf-cache-status: HIT
# cf-ray: 8a1b2c3d4e5f-LAX
# 解读:
# s-maxage=3600 → CDN 缓存 1 小时
# age=1847 → 已缓存 1847 秒(约 30 分钟)
# x-cache: HIT → 缓存命中
# cf-ray 后缀 LAX → 洛杉矶 PoP

在 Chrome DevTools 中观察更直观:

  1. 打开 DevTools → Network 面板
  2. 右键列头 → 勾选 AgeCache-ControlX-Cache
  3. 刷新页面,观察每个资源的缓存状态
  4. 对比首次加载(MISS)和再次刷新(HIT)的差异

七、本章小结#

主题核心要点
CDN 动机缩短物理距离、消除单点故障、降低带宽成本
任播路由同一 IP 多点宣告,BGP 自动就近路由,配合 DNS 调度
缓存策略Cache Key + Vary 决定缓存粒度,s-maxage 控制共享缓存,stale-while-revalidate 异步刷新
回源优化连接复用、请求合并、源站屏蔽减少回源压力
动态加速TCP 调优、路由优化、连接预建弥补缓存无法覆盖的场景
CDN 安全边缘流量稀释抗 DDoS、WAF 应用层防护、TLS 卸载、源站屏蔽

CDN 把数据搬到离用户更近的地方,本质上是互联网”端到端”原则的一次务实妥协——在纯粹的端到端和极致的用户体验之间,CDN 选择了后者。理解了 CDN 的缓存、调度和安全机制,再看 DNS域名系统 的 CNAME 委派、BGP与域间路由 的任播宣告、HTTP协议演进 的缓存语义,会发现它们都在为 CDN 这张分布式网络服务。

支持与分享

如果这篇文章对你有帮助,欢迎支持作者或分享给更多人

CDN与内容分发:数据包的捷径
https://blog.souloss.com/posts/internet-architecture/cdn-and-content-delivery/
作者
Souloss
发布于
2022-08-30
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

相关文章 智能推荐
1
数据中心与SDN网络:数据包的终点与控制
互联网运作 数据包经过CDN边缘节点缓存与分发后,最终要抵达源站服务器——数据中心。从传统树形拓扑到CLOS脊叶架构、从VLAN到VXLAN overlay、从分布式控制到SDN集中管控、从硬件负载均衡到服务网格,本章讲述数据中心网络的演进脉络与核心机制。
2
以太网与交换:数据包离开网卡
互联网运作 数据包从应用层到达网卡后,如何变成以太网帧离开主机?802.3帧结构、MAC地址、网卡发送流程、交换机转发逻辑、VLAN隔离——从内核到交换机的完整链路追踪。
3
互联网全景:一个数据包的旅程
互联网运作 宏观视角下的互联网架构——沙漏模型、分层架构、封装与解封装全链路预览、端到端原则,用一个数据包从浏览器到服务器的完整路径串联所有后续章节的核心概念。
4
ARP与首跳路由:数据包找到出路
互联网运作 数据包知道目的IP,但如何找到下一跳的MAC地址?ARP请求/应答、免费ARP、代理ARP、路由表查找与最长前缀匹配——从主机到路由器的完整链路追踪,含Wireshark抓包证据。
5
BGP与域间路由:互联网的外交系统
互联网运作 数据包跨组织转发靠什么?自治系统概念、BGP会话建立与路由通告、AS_PATH/LOCAL_PREF/MED等选路属性、策略路由与路由过滤——一个跨AS数据包转发的完整追踪。