You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Cloudflare CDN下Nginx源站缓存失效及与Apache的差异咨询

嗨,咱们来聊聊为啥你的Nginx源站在Cloudflare上缓存一直是DYNAMIC,而Apache却正常——这俩服务器在缓存相关的配置和行为上有不少关键差异,我给你拆解一下:

核心差异及排查方向

1. 默认响应头的差异

Apache的默认配置(尤其是开启了mod_expiresmod_headers模块时)往往会自动给静态资源返回允许缓存的Cache-ControlExpires头,比如public, max-age=86400,这让Cloudflare很容易识别出可缓存的内容。

而Nginx默认就“保守”多了:它通常会给动态内容返回Cache-Control: no-cache, no-store, must-revalidate,甚至加上Pragma: no-cache这类强禁止缓存的头。哪怕你在Cloudflare设了“缓存所有内容”的页面规则,只要源站返回了no-store这类头,Cloudflare会优先遵守源站的设置,直接标记为DYNAMIC。

快速排查:用curl -I https://你的Nginx源站域名/某个资源,对比Apache源站的响应头,重点看Cache-ControlPragmaExpires这几个字段。

2. 动态内容的缓存头配置逻辑

Apache的mod_cachemod_fcgid等模块默认会对动态内容(比如PHP)的缓存处理更灵活,甚至很多主机面板(比如cPanel)会自动给动态内容添加合适的缓存头。

但Nginx不一样——它默认不会主动给动态内容设置缓存头。如果你的Nginx配置里没有明确添加add_header Cache-Control "public, max-age=3600";这类规则,动态内容就会一直带着“不可缓存”的标记,Cloudflare自然不会缓存它。

3. Cookie处理的差异

这是很容易被忽略的点:Nginx默认可能会给所有响应(包括静态资源)带上Cookie(比如PHPSESSID),而Cloudflare默认会跳过带Cookie的请求的缓存(因为Cookie意味着内容可能是个性化的)。

反观Apache,很多默认配置会给静态资源自动去掉Cookie,或者你的Apache配置里已经做了相关设置。如果Nginx的静态资源响应头里带着Cookie,Cloudflare会直接判定为动态内容,不会缓存。

解决方法:在Nginx的静态资源location块里添加:

location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
    proxy_hide_header Set-Cookie;
    fastcgi_hide_header Set-Cookie;
    add_header Cache-Control "public, max-age=86400" always;
}

4. 缓存规则的优先级细节

Cloudflare的页面规则优先级通常高于源站响应头,但有两个例外:如果源站返回Cache-Control: private或者no-store,Cloudflare会严格遵守源站的设置,页面规则的“缓存所有内容”会失效。

你的Apache源站大概率没有返回这些强禁止的头,所以页面规则能正常生效;但Nginx默认返回的就是这类头,导致页面规则起不了作用。

快速修复:在Nginx的全局或location配置里强制设置允许缓存的头:

server {
    # ...其他配置
    add_header Cache-Control "public, max-age=3600" always;
    # 如果是PHP动态内容,还可以加上这些
    fastcgi_cache_bypass $http_pragma;
    fastcgi_no_cache $http_pragma;
}

5. Vary头的差异

Apache默认可能不会返回Vary: *这类头,但Nginx在某些配置下(比如开启了某些动态模块)会返回Vary: *。这个头会告诉Cloudflare“每个请求的内容都可能不同”,直接导致无法缓存。

排查:检查Nginx响应头里有没有Vary: *,如果有,在配置里去掉或者改成具体的字段(比如Vary: Accept-Encoding)。

快速排查步骤总结
  1. curl -I分别请求Apache和Nginx源站的同一个资源,对比响应头的差异,重点看Cache-ControlSet-CookieVary字段。
  2. 在Nginx配置里添加强制缓存头,重启Nginx后测试Cloudflare的缓存状态。
  3. 确认Cloudflare的页面规则确实匹配了Nginx源站的域名(有没有规则顺序错误、匹配路径不对的情况)。

内容的提问来源于stack exchange,提问作者Almighty

火山引擎 最新活动