接入CDN后,伪静态网站常见问题包括:缓存错配导致动态页面被缓存、URL重写后CDN缓存键不正确、带参数的请求被错误缓存、登录或后台相关页面被缓存引发数据混乱、以及资源回源失败因为CDN未正确转发必要请求头或Query String。
主要原因是CDN在边缘节点做缓存时依赖缓存键(Cache Key),而伪静态通过Rewrite将“伪装后”的静态路径转到内部动态脚本,若CDN没有保留原始请求路径或必要的参数,回源与缓存会出现不一致。
必须确保CDN转发必要的请求头(如Host、Cookie、Authorization视情况)、是否保留Query String,以及如何构建缓存键以区分不同页面。
开发测试与线上环境需一致,避免本地伪静态与生产CDN行为差异导致的问题。
核心思路是让服务器的Rewrite规则对原始请求路径生效,同时保证CDN回源时以相同路径请求。推荐在服务器端基于请求URI进行内部重写,而不是外部重定向。
location / {
try_files $uri $uri/ /index.php?$args;
}
使用try_files可以将不存在的静态路径内部转发到index.php并保留$query string($args),这样CDN回源请求的URI仍然是伪静态路径,回源参数也被保留。
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?$1 [L,QSA]
使用QSA(Query String Append)保证参数传递,且使用内部重写(不使用R=301)避免客户端看到重定向。
在CDN侧,需要明确哪些URI可以长期缓存(如静态资源、可缓存页面),哪些需要回源或忽略缓存(如用户中心、购物车)。
缓存键通常包含协议、Host、URI、但是否包含Query String取决于业务。对于伪静态,建议默认以完整URI为键(不包含可变参数),对需要区分参数的页面则启用Query String作为键的一部分。
1) 静态资源(/static/, .css, .js, .jpg)设置长TTL并按路径缓存; 2) 列表页可缓存短TTL并按分页参数(page)包含Query String; 3) 详情页若URL已包含标识(如/product/123.html),则不包含Query String以提高命中。
通过规则检测Cookie或Authorization头,若请求带有登录相关Cookie则设为不缓存或直接回源。
缓存穿透指大量不命中请求直接打到源站,可能因参数泛滥或爬虫攻击。对策包括参数白名单、请求频率限制以及对热点URL预热。
在CDN或边缘节点对Query String做白名单,只保留影响内容的参数,其他参数忽略或去重;对URL大小写和结尾斜杠做归一化,减少缓存碎片。
部署上线或内容更新时,使用API自动化清理相关URL或按前缀清理。对伪静态页面,优先按伪静态路径清除,例如清除/product/123.html而不是清除带参数的多个变体。
清理后可触发预热(主动请求CDN边缘缓存)以降低首次访问回源压力。
调试分为本地服务器行为验证和CDN边缘行为验证两个层面。
直接对源站发起请求(在本地hosts指向源IP),检查响应头(Cache-Control、Set-Cookie、Vary)、返回的页面是否按预期被内部Rewrite处理。使用日志查看是否命中文件或走了index.php。
使用curl带上真实Host向CDN节点请求,观察响应头中是否包含CDN相关字段(如 X-Cache 或 Age),并验证是否命中缓存。示例:curl -I -H "Host: example.com" https://example.com/product/123.html
1) 若边缘不命中且回源频繁,检查Cache-Control或Set-Cookie是否禁止缓存;2) 若页面被错误缓存,检查是否忽略了Cookie或Authorization;3) 若URL被重写导致404,检查CDN是否在回源时修改了URI或去掉了必要参数。
建议在CI流程中加入若干关键URL的缓存命中与内容校验,用脚本定期检测并报警。
