香港与美国服务器部署网站,页面缓存和CDN缓存如何分层

先确定缓存分层,而不是先延长缓存时间
常见的运维现场是:网站分别部署在香港服务器或美国服务器,接入 CDN 后,静态资源命中率不错,但首页和文章页有时仍然慢;更新内容后,部分访问者却继续看到旧页面。此时应先区分缓存发生在哪一层,再判断是回源慢、页面未命中,还是失效没有传递到边缘节点。
页面、对象和查询缓存解决的问题不同:页面缓存保存可复用的完整响应;对象缓存保存应用生成的数据;查询缓存若存在,应针对确定、可重复的数据库结果,并考虑数据更新后的失效。CDN 缓存则位于访问者与源站之间,适合保存可安全共享的响应。常见的分层方式是:应用侧对象缓存减少重复计算,源站页面缓存减少重复渲染,CDN 缓存减少跨网络回源;浏览器缓存负责用户本地的静态资源。对于含个人信息或登录状态的响应,应绕过共享缓存。
香港服务器与美国服务器对比时,缓存规则本身并不会因为部署地区而改变。部署位置会影响访问者到 CDN 边缘、以及边缘到源站的网络路径,因此缓存命中能减少回源的价值可能不同,但不能据此推断固定的速度差异。应根据实际访问来源、CDN 命中情况和源站日志验证,而不是单凭地区调整缓存时长。
先划定哪些内容可以缓存
配置前先把页面按响应内容分类。判断标准不是“它是不是网页”,而是同一个缓存键对应的响应能否安全地提供给不同访问者。
| 内容类型 | 推荐层级 | 缓存边界与失效方式 |
|---|---|---|
| 带版本号的图片、样式表、脚本、字体 | CDN、浏览器 | 文件内容不变时可长时间复用;发布新内容时更换文件版本或路径 |
| 不含用户状态的公开文章页、分类页 | 源站页面缓存、CDN(按需) | 确认响应不因登录身份、地域化设置等变化;发布或编辑后按页面地址失效 |
| 登录后的个人页、购物车、账户信息 | 通常不进入共享页面缓存 | 返回明确的私有或禁止缓存控制;检查 CDN 与源站均未覆盖该规则 |
| 站内搜索、筛选、分页结果 | 默认谨慎处理 | 只有参数范围明确、结果可共享时才缓存;避免不同查询误用同一缓存键 |
| 菜单、站点配置、热门内容等应用数据 | 对象缓存 | 由应用设定数据标识和失效时机;内容更新时删除或重建对应对象 |
部署前还要确认:源站可以被 CDN 正常回源;站点已经能区分匿名访问和登录访问;应用能在内容变更时触发缓存失效,或运维人员可以按 URL 清除缓存;测试环境或低流量时段可用于验证。若无法判断某个响应是否含用户数据,先不启用共享缓存。
按访问链路逐层配置
1. 先处理浏览器和 CDN 的静态资源
对内容带版本号的静态文件,可由源站返回类似以下响应头:
Cache-Control: public, max-age=31536000, immutable
只有文件名或 URL 中包含版本信息,且发布时会生成新地址,这类长期缓存才安全。若文件会在原地址直接覆盖,应缩短缓存时间,或在更新后同时清理 CDN 和浏览器无法主动清理的旧缓存。
HTML 页面不要直接套用静态资源的长期策略。公开页面可设置较短的共享缓存时间,具体时长应结合更新频率、CDN 的失效能力和业务容忍度确定;个人页面则应由应用返回 private 或 no-store 等控制信息。应检查 CDN 的缓存规则是否尊重源站响应头,避免一条“所有状态码、所有路径均缓存”的规则覆盖应用的隐私边界。
CDN 缓存键至少要覆盖主机名和路径。查询参数需逐项评估:如果参数会改变页面内容,应纳入缓存键;如果只是统计来源参数,且确认不影响响应,可在 CDN 侧按规则处理。不要不加判断地忽略全部查询参数,否则不同筛选条件或分页可能拿到同一份页面。
2. 再决定是否启用源站页面缓存
对于匿名访问较多、页面内容可共享的网站,可在源站增加页面缓存,减少重复执行模板渲染和数据库读取。以下为 Nginx 配合 PHP-FPM 的示意配置,适用于已配置 fastcgi_pass 的环境;/run/nginx-cache、缓存区域大小、PHP 上游地址和站点路径都需按实际环境调整。
在 Nginx 的 http 配置段定义缓存区域:
fastcgi_cache_path /run/nginx-cache levels=1:2 keys_zone=site_pages:20m
inactive=30m max_size=1g;
map $request_method $skip_method {
default 1;
GET 0;
HEAD 0;
}
map $http_cookie $skip_cookie {
default 0;
~*"(session|auth|logged_in)" 1;
}
在对应站点的 PHP 处理位置中加入缓存控制。下面的 fastcgi_pass 应替换为该站点已有的 PHP-FPM 配置,不要照搬未经核实的套接字路径。
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_cache site_pages;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache_bypass $skip_method $skip_cookie;
fastcgi_no_cache $skip_method $skip_cookie $upstream_http_set_cookie;
fastcgi_cache_valid 200 5m;
add_header X-Origin-Cache $upstream_cache_status always;
}
该示例只允许 GET、HEAD 请求进入缓存,并对带有常见会话标记的 Cookie 跳过缓存;应用返回 Set-Cookie 时也不保存响应。Cookie 名称必须按实际系统核实,不能把示例中的几个关键词当成完整的登录识别方案。登录、账户、结算等路径还应根据应用路由明确排除。生产环境如不希望响应暴露缓存状态,可在验证后移除 X-Origin-Cache。
示例中的缓存有效期只是配置示范,不代表适用于所有网站。源站页面缓存和 CDN 缓存都启用时,需明确谁负责失效:例如源站页面变更后先清除源站对应页面缓存,再清除 CDN 对应 URL。若 CDN 已缓存旧页面,而源站页面缓存也仍然是旧内容,仅清除其中一层可能无法得到新内容。具体先后应结合回源路径验证。
对象缓存应由应用在数据读取和写入时管理:读取时使用稳定的数据标识,更新文章、菜单或配置后清除相关对象,必要时更新版本号。数据库查询结果若被缓存,也必须确认查询条件完整、结果不含用户专属数据,并在相关表数据变化时失效。不要为了提高命中率而缓存无法说明失效条件的查询结果。
从低风险测试到线上启用
按以下顺序操作,先观察现状,再逐层打开缓存:
- 备份配置并记录基线。 保存将要修改的 Nginx 配置和 CDN 当前规则,记录典型页面的响应头、状态码及页面内容。确认有可用的配置恢复方式。修改共享缓存配置可能影响多个页面,不宜在高峰期直接大范围启用。
- 检查应用的缓存边界。 分别访问匿名页面和登录页面,检查响应头、Cookie 和内容差异。登录页面或含用户数据的响应不应因为 URL 相同而被其他访问者复用。若应用无法正确区分这些响应,先修正应用的缓存控制,不要依赖 CDN 猜测。
- 先开放少量静态资源。 使用带版本号的文件验证 CDN 规则是否生效。确认新版本使用新 URL 后,再逐步覆盖其他静态路径。旧文件仍可被访问并不一定表示规则错误,可能只是缓存尚未过期。
- 在源站小范围开启页面缓存。 先选择一两个确认可共享的匿名页面。检查配置语法后再平滑加载;具体服务名和管理命令取决于操作系统及安装方式,先核实当前服务名称。
nginx -t
若检查成功,再按实际系统的 Nginx 服务名称执行平滑重载。若检查失败,不要重载;根据报错修正配置,或恢复备份后重新检查。
- 最后启用 CDN 的 HTML 缓存规则。 先限定公开页面路径和可缓存状态,再确认 CDN 的缓存键、查询参数策略、Cookie 处理和源站响应头规则。完成后,通过 CDN 提供的缓存清理功能按 URL 测试失效;不要一开始清空整个站点缓存,以免造成不必要的回源波动。
验证命中、失效和隐私边界
在源站配置了示例响应头后,可用 curl 检查同一公开页面的重复请求。命令应在能够访问目标站点的终端执行,替换为实际域名和页面路径:
curl -sSI https://example.com/news/
curl -sSI https://example.com/news/
检查 X-Origin-Cache 是否先显示未命中、随后出现命中;若一直未命中,检查请求方法、Cookie、应用返回的 Set-Cookie、状态码和缓存键。若返回命中但页面内容不应共享,应立即关闭该路径的缓存并核查缓存键与绕过条件。
再分别从 CDN 访问公开页面和个人页面,检查 CDN 的命中状态或管理面板记录,并比对响应内容。成功标准不是“响应头显示命中”这一项,而是公开页面内容正确、更新后能够按预期失效、登录页面始终返回当前用户自己的内容。响应头名称和状态含义因 CDN 服务而异,应以当前服务的文档和控制台为准。
更新一篇测试文章后,按既定流程清除对应的源站页面缓存和 CDN URL,再重新请求。若源站内容已更新、CDN 仍旧,应检查 CDN 失效规则、缓存键和边缘有效期;若 CDN 已回源但页面仍旧,应检查源站页面缓存或应用对象缓存;若同一 URL 对不同用户显示相同的个人信息,应立刻禁用相关共享缓存、清理受影响缓存,并排查 Cookie、身份识别和缓存键,不能仅靠缩短有效期处理。
出现异常时如何回退
如果出现页面更新不及时、用户内容串用或异常页面被缓存,优先关闭受影响路径的 CDN 缓存,并清除相关 URL;随后在源站对对应页面绕过缓存。不要先清空全部对象缓存或数据库缓存,因为影响范围可能远大于故障页面。
若问题发生在 Nginx 配置变更后,恢复变更前备份,先执行 nginx -t;检查通过后再按当前系统确认的服务名称平滑重载。上述操作涉及站点级缓存行为,回滚可能增加源站请求量,应同时观察源站资源和错误日志。无法确认配置归属、服务名称或影响范围时,应先核对现有运行配置,不要直接覆盖文件或重启服务。
复盘时容易漏掉的事项包括:移动端或不同主机名是否走了另一套缓存规则;带查询参数的页面是否被错误合并;应用更新后对象缓存是否同步失效;源站和 CDN 的有效期是否形成了不可预期的叠加;登录响应是否设置了正确的私有缓存控制;静态资源是否真的使用版本化 URL。香港服务器与美国服务器都应按同一套检查项验证,只是应分别观察各自实际的 CDN 命中、回源和内容更新结果。