CDN配置完成后,页面可以正常打开,但源站日志依然有大量请求,这往往说明CDN没有真正接管流量。

单纯看浏览器加载速度并不准确,因为本地缓存和网络波动会干扰判断。更可靠的做法是从响应头中寻找缓存节点的交互记录,其中X-Cache字段最直观。下面介绍如何通过curl命令获取这些信息,并判断CDN是否真正生效。
理解X-Cache响应头与常见取值
X-Cache并不是HTTP标准头,而是CDN厂商在边缘节点响应用户请求时附加的自定义头,用来表示该请求命中了缓存还是回源。不同厂商使用的头名称可能不同,例如Cloudflare使用CF-Cache-Status,阿里云早期产品使用X-Cache,部分对象存储加速可能返回X-Cache-Lookup或X-Swift-CacheTime。本文以X-Cache为主,因为多数自建CDN和商业CDN都保留了这一字段。
X-Cache常见取值有以下几类。HIT表示请求命中缓存节点,内容直接从CDN缓存返回,没有访问源站。MISS表示节点没有该资源的缓存,或者缓存已经失效,需要回源拉取。EXPIRED表示缓存已过期,但节点可能尝试与源站协商,具体是否回源取决于配置。BYPASS通常表示请求因为规则设置、Cookie或请求头条件而绕过缓存。DYNAMIC则说明该请求被识别为动态内容,不会走静态缓存逻辑。了解这些取值有助于快速判断CDN行为。
HTTP/2 200 server: nginx date: Mon, 09 Jun 2025 10:21:30 GMT content-type: text/html x-cache: HIT via: http/1.1 CDN-CACHE-1 age: 135
上述响应头示例中,x-cache状态为HIT,同时出现via字段,表明请求经过了CDN边缘节点,节点直接返回了缓存内容。如果x-cache是MISS,则说明这次请求回源了。要注意的是,单次MISS并不代表CDN异常,因为该资源可能是首次被访问,节点还没有建立缓存。
使用curl命令获取响应头并判断命中
很多人习惯使用curl -I来查看响应头,但HEAD请求和真实GET请求在部分CDN上的处理逻辑并不完全一致,有些节点对HEAD请求不返回X-Cache,或者返回的状态与GET不同。因此更推荐使用curl -s -D - -o /dev/null发起一次GET请求,只输出响应头,丢弃响应体,这样能最大程度模拟真实用户访问。
curl -s -D - -o /dev/null https://ipipp.com/index.html
命令执行后会输出完整的响应头,其中就包括X-Cache字段。如果只需要过滤关键信息,可以配合grep使用,减少干扰内容。
curl -s -D - -o /dev/null https://ipipp.com/index.html | grep -i "x-cache"
如果没有看到X-Cache,可以先检查请求是否真正经过CDN。使用curl -v查看连接过程,观察TLS证书颁发者、解析到的IP以及响应头中的Server和Via字段。如果证书仍然是源站证书,说明CDN可能没有接管HTTPS流量;如果Via字段缺失,则请求可能直接到了源站。
curl -v -o /dev/null https://ipipp.com/index.html 2>&1 | grep -i "x-cache\|server\|via\|subject"
通过对比源站直连和通过CDN访问的响应头,可以更清楚地看出差异。源站通常不会返回X-Cache,而CDN节点会附加缓存状态和Via信息。这个步骤能帮助确认CDN是否部署在请求链路上。
通过连续请求验证缓存行为与回源判断
仅凭一次请求的MISS状态难以判断CDN是否生效。更合理的做法是连续请求两次,观察缓存状态的迁移。第一次请求资源时,如果节点没有缓存,会返回MISS并回源拉取;第二次请求同一资源,如果CDN工作正常,应该返回HIT,同时Age字段开始增长。
for i in 1 2; do curl -s -D - -o /dev/null https://ipipp.com/app.js | grep -i "x-cache\|age" done
执行后可能会看到第一次输出MISS,第二次输出HIT。如果两次都是MISS,说明CDN没有缓存该资源,原因可能包括源站返回了禁止缓存的响应头、CDN规则未匹配该路径,或者资源本身被识别为动态内容。此时需要进一步检查源站的Cache-Control和Expires字段。
查询参数也会影响缓存命中。例如https://ipipp.com/app.js?v=1和https://ipipp.com/app.js?v=2会被CDN视为不同的缓存键,各自独立回源。如果源站不希望查询参数影响缓存,可以在CDN配置中开启忽略查询字符串的选项。Cookie同样可能导致缓存绕过,尤其是当CDN配置了根据Cookie值区分不同内容时。
curl -s -D - -o /dev/null "https://ipipp.com/app.js?v=1" | grep -i "x-cache" curl -s -D - -o /dev/null "https://ipipp.com/app.js?v=2" | grep -i "x-cache"
如果需要强制绕过CDN缓存进行对比测试,可以在请求头中加入缓存控制指令,让节点直接回源。执行下面命令,观察返回状态是否从HIT变为MISS或者BYPASS。
curl -H "Cache-Control: no-cache" -s -D - -o /dev/null https://ipipp.com/app.js | grep -i "x-cache"
如果添加了no-cache请求头后仍然返回HIT,说明CDN配置可能忽略了客户端缓存控制头,或者缓存规则本身存在异常。通过这种对比可以进一步确认CDN的缓存策略是否符合预期。
CDN未生效的常见排查维度
当X-Cache始终不出现,或者请求没有经过CDN节点时,需要从域名解析开始排查。使用dig或nslookup查看域名是否解析到CDN厂商提供的CNAME地址。如果域名仍然直接解析到源站IP,说明切换尚未完成或本地DNS缓存未刷新。
dig www.ipipp.com CNAME nslookup www.ipipp.com
如果解析已经指向CDN,但响应头仍然没有X-Cache,需要检查源站响应策略。源站返回Cache-Control: private或no-store时,CDN通常不会缓存内容,这会导致每次请求都回源。使用curl直接请求源站IP,加上Host头,观察源站响应头中的缓存字段,可以快速判断源站是否允许CDN缓存。
curl -s -D - -o /dev/null -H "Host: www.ipipp.com" http://源站IP/index.html | grep -i "cache-control\|expires\|set-cookie"
另外,CDN控制台中的加速规则是否覆盖到目标路径也很关键。如果规则只缓存静态目录,而请求的是根路径或动态接口,就不会产生缓存命中。结合CDN日志和源站访问日志,对比相同请求是否同时出现在源站,可以确认是否有绕过CDN的流量。
通过X-Cache头结合辅助字段,可以定位大部分CDN未生效的问题。命令行验证成本低、反馈直接,适合在配置变更后快速检查,也能作为自动化监控的一部分。掌握curl查看响应头的方法,对日常排查CDN故障和优化加速效果都很有帮助。