Varnish处理流程的三个主要子程序

1. vcl_recv – 请求接收阶段

作用:客户端请求到达时的第一个处理点
主要任务

  • 检查请求方法(GET、POST等)
  • 处理认证和授权
  • 决定是否查找缓存
  • 修改请求头

2. vcl_backend_response – 后端响应阶段

作用:收到后端服务器响应后的处理
主要任务

  • 设置缓存TTL(存活时间)
  • 根据响应头决定是否缓存
  • 处理ESI(Edge Side Includes)
  • 修改响应头

3. vcl_deliver – 交付阶段

作用:向客户端发送响应前的最后处理
主要任务

  • 添加调试头信息
  • 修改最终响应头
  • 记录日志信息

Varnish完整处理流程

return (action) 返回值详解

缓存决策类

返回值含义使用场景
return (pass)跳过缓存,直接访问后端已登录用户、POST请求
return (pipe)直接透传,不干预连接大文件下载、WebSocket
return (lookup)查找缓存(默认行为)普通可缓存请求
return (hash)生成缓存键并查找需要自定义缓存键时

终止类

返回值含义使用场景
return (synth)返回合成响应错误页面、维护模式
return (purge)清除缓存PURGE请求处理
return (restart)重新开始处理修改请求后重新处理

详细使用示例

vcl_recv 中的典型用法

varnish

sub vcl_recv {
    # 已登录用户跳过缓存
    if (req.http.Cookie ~ "wordpress_logged_in") {
        return (pass);
    }
    
    # POST请求直接到后端
    if (req.method == "POST") {
        return (pass);
    }
    
    # 静态文件直接查找缓存
    if (req.url ~ "\.(css|js|png|jpg)$") {
        return (hash);
    }
    
    # 默认行为:查找缓存
    return (hash);
}

vcl_backend_response 中的用法

varnish

sub vcl_backend_response {
    # 设置HTML缓存10分钟
    if (beresp.http.Content-Type ~ "text/html") {
        set beresp.ttl = 10m;
    }
    
    # 后端设置不缓存的响应
    if (beresp.http.Cache-Control ~ "no-cache") {
        set beresp.uncacheable = true;
        return (deliver);
    }
}

vcl_deliver 中的用法

varnish

sub vcl_deliver {
    # 添加调试头信息
    if (obj.hits > 0) {
        set resp.http.X-Cache = "HIT";
        set resp.http.X-Cache-Hits = obj.hits;
    } else {
        set resp.http.X-Cache = "MISS";
    }
}

重要特点

  1. 固定名称:这些子程序名称是Varnish固定的,不能更改
  2. 执行顺序:严格按照Varnish的处理流程顺序执行
  3. 返回值约束:每个子程序只能返回特定的action值
  4. 上下文相关:不同的子程序中有不同的可用变量和对象

实际应用建议

  • return (pass):谨慎使用,过多会导致缓存命中率下降
  • 缓存策略:根据内容类型设置不同的TTL
  • 调试头:在vcl_deliver中添加缓存状态头便于调试
  • 错误处理:使用return (synth)返回友好的错误页面

理解这些概念对于配置高效的Varnish缓存策略至关重要。

Scroll to Top