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

关于Varnish配置代码功能及缓存逻辑的技术问询

关于Varnish配置代码功能及缓存逻辑的技术问询

Hey there! Let's walk through your Varnish vcl_backend_response code line by line to figure out what it does, whether it's caching your requests, and where it goes wrong.

First, here's your code for reference:

sub vcl_backend_response {

if (beresp.status != 200) {

return (pass);

}

set beresp.http.X-Backend = beresp.backend.name;

unset beresp.http.cookie;

unset beresp.http.Set-Cookie;

if (bereq.http.x-render-type == "test" && beresp.http.Content-Type ~ "text/html") {

set beresp.http.Cache-Control = "no-store";

}

set beresp.http.Cache-Control = "no-store";

if (bereq.http.x-render-type == "test" && beresp.http.Content-Type ~ "text/html") {

return (pass);

}

return (deliver);

}

1. 代码逐行解析

  • 非200状态码处理:如果后端返回的状态码不是200(比如404、500这类错误),直接返回pass——这类请求完全不会被缓存,每次都会直接回源获取内容。
  • 添加自定义响应头:给响应加上X-Backend头,值是处理请求的后端服务器名称,方便你排查是哪个后端节点返回的内容,用于调试。
  • 清除Cookie相关头:删除响应里的cookie和Set-Cookie头,这是常见的缓存优化操作——默认情况下,Varnish不会缓存带Cookie的请求/响应,清除这些头能避免缓存被跳过。
  • 第一个条件块:如果请求头x-render-type为"test",且响应是HTML内容,就设置Cache-Control: no-store,告诉Varnish和浏览器不要缓存该响应。但这个设置马上会被后面的代码覆盖,完全无效。
  • 全局强制设置Cache-Control:不管前面的条件块有没有触发,这里都会把所有响应的Cache-Control设为no-store,直接让前面的条件块变成冗余代码。
  • 第二个条件块:再次判断x-render-type=test且是HTML内容的情况,返回pass——直接跳过缓存,把后端响应原样传给客户端。
  • 默认交付逻辑:如果前面的条件都没触发,就把响应交给Varnish的交付流程,但因为全局设置了no-store,最终还是不会缓存。

2. 这段代码会缓存客户端请求吗?

答案是:完全不会缓存任何请求,核心原因有两个:

  • 全局的set beresp.http.Cache-Control = "no-store";强制Varnish不存储任何响应到缓存中,覆盖了所有其他缓存相关设置。
  • 就算没有全局设置,x-render-type=test的HTML请求也会通过return(pass)跳过缓存;非这类请求走到return(deliver)后,也会因为no-store头无法被缓存。

3. 代码存在的问题

  • 冗余无效的条件块:第一个设置no-store的条件块,后续被全局设置完全覆盖,没有任何实际作用,可以直接删除。
  • 全局禁用缓存:这是最关键的问题——强制给所有响应加上no-store头,直接废掉了Varnish的核心缓存功能。
  • 逻辑顺序不合理:第二个条件块放在全局缓存头设置之后,虽然不影响功能,但从代码可读性来说,应该先判断是否要跳过缓存,再处理缓存头设置。

修复建议(如果需要启用缓存)

如果希望Varnish正常发挥缓存作用,可以参考下面的修改版本:

sub vcl_backend_response {
    # 非200响应直接跳过缓存
    if (beresp.status != 200) {
        return (pass);
    }

    # 添加调试用的后端标识头
    set beresp.http.X-Backend = beresp.backend.name;
    # 清除Cookie以允许缓存
    unset beresp.http.cookie;
    unset beresp.http.Set-Cookie;

    # 针对test类型的HTML请求禁用缓存
    if (bereq.http.x-render-type == "test" && beresp.http.Content-Type ~ "text/html") {
        set beresp.http.Cache-Control = "no-store";
        return (pass);
    }

    # 设置默认缓存时长(可根据业务需求调整)
    set beresp.ttl = 1h;
    # 交付响应到缓存和客户端
    return (deliver);
}

这个版本:

  • 移除了冗余的全局no-store设置
  • 提前处理需要跳过缓存的请求逻辑
  • 给可缓存的响应设置了默认TTL(缓存有效期)
  • 仅针对特定的test HTML请求禁用缓存

备注:内容来源于stack exchange,提问作者Morteza

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.22 14:13:11