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";
}
}
重要特点
- 固定名称:这些子程序名称是Varnish固定的,不能更改
- 执行顺序:严格按照Varnish的处理流程顺序执行
- 返回值约束:每个子程序只能返回特定的action值
- 上下文相关:不同的子程序中有不同的可用变量和对象
实际应用建议
return (pass):谨慎使用,过多会导致缓存命中率下降- 缓存策略:根据内容类型设置不同的TTL
- 调试头:在
vcl_deliver中添加缓存状态头便于调试 - 错误处理:使用
return (synth)返回友好的错误页面
理解这些概念对于配置高效的Varnish缓存策略至关重要。