You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Symfony Sulu集成Varnish ESI失效问题排查求助

排查ESI失效问题的具体步骤

1. 确认主页面的缓存生命周期

  • 用curl -I http://your-domain/your-page检查主页面的Cache-Control头:如果主页面设置了很长的max-age(比如1天)且没有must-revalidate,Varnish会一直返回缓存的主页面,根本不会去后端拉取带最新ESI标签的版本。
  • 用varnishlog -g request -q "ReqUrl ~ '/your-page'"查看主页面的缓存命中情况:如果一直显示Hit,说明主页面缓存没过期,Varnish不会触发新的后端请求,自然不会解析新的ESI。
  • 确认主页面响应头包含Surrogate-Control: content="ESI/1.0":这个是Varnish开启ESI解析的核心触发条件,必须由Symfony后端返回,不能只在VCL里配置。

2. 检查ESI片段的缓存与个性化配置

  • 直接请求ESI片段URL(比如curl http://localhost:8000/esi/login-button),确认10秒后内容是否更新:如果直接请求后端都不更新,问题出在Symfony控制器,和Varnish无关。
  • 检查片段的响应头:必须包含Cache-Control: public, max-age=10, shared-max-age=10,关键是要加Vary: Cookie——登录按钮是用户个性化内容,没有Vary: Cookie的话,Varnish会把登录/未登录状态的片段缓存成同一个版本,即使过期刷新也不会变。
  • 用varnishlog -g request -q "ReqUrl ~ '/esi/login-button'"查看片段的缓存命中:10秒后应该出现Miss,如果一直Hit,说明片段的缓存策略被覆盖(比如Symfony的其他缓存层、VCL里强制设置了更长的缓存时间)。

3. 验证VCL的ESI配置正确性

  • 确保vcl_recv里给后端发送了ESI支持声明:
    sub vcl_recv {
        # 告诉Symfony可以返回ESI标签
        set req.http.Surrogate-Capability = "ESI/1.0";
    }
    
  • 确保vcl_backend_response里正确开启ESI解析,且逻辑顺序正确(要在设置beresp.cacheable之前):
    sub vcl_backend_response {
        # 检测到后端返回的Surrogate-Control头,开启ESI解析
        if (beresp.http.Surrogate-Control ~ "ESI/1.0") {
            unset beresp.http.Surrogate-Control;
            set beresp.do_esi = true;
        }
        # 其他缓存配置放在后面
        if (beresp.cacheable) {
            # 你的xkey等缓存失效配置
        }
    }
    
  • 确认Varnish版本支持ESI:Varnish 6.x及以上版本默认支持,老版本可能需要额外编译模块。

4. 排查Docker链路与额外缓存层

  • 确认Varnish的后端指向NGINX(8000端口),而不是直接指向PHP(9000端口):Varnish无法直接处理FastCGI请求,必须通过NGINX转发。
  • 检查NGINX是否开启了自身的缓存:如果NGINX配置了proxy_cache,会直接返回缓存的页面/片段,绕过Varnish的ESI解析。
  • 检查Sulu的CMS缓存:Sulu自带页面缓存机制,可能覆盖了Symfony的ESI设置,需要在Sulu的页面配置里禁用静态缓存,或者配置支持ESI。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 10:43:33