Varnish配置基础 #

一、配置文件概述 #

1.1 配置文件位置 #

文件 位置 说明
default.vcl /etc/varnish/default.vcl 主VCL配置文件
secret /etc/varnish/secret 管理接口密钥
varnish.params /etc/varnish/varnish.params 启动参数(RHEL系)

1.2 配置层次结构 #

text
Varnish配置
├── 启动参数配置
│   ├── 监听端口
│   ├── 存储配置
│   └── 运行时参数
├── VCL配置
│   ├── 后端定义
│   ├── ACL定义
│   └── 子程序
└── 管理配置
    ├── 密钥文件
    └── 管理端口

二、VCL语言基础 #

2.1 VCL版本声明 #

vcl
vcl 4.1;

VCL版本说明:

版本 Varnish版本 特性
4.0 4.x 基础VCL
4.1 6.x+ 增强特性、新变量

2.2 注释语法 #

vcl
# 这是单行注释

// 这也是单行注释

/*
 * 这是多行注释
 * 可以跨越多行
 */

2.3 基本语法规则 #

vcl
vcl 4.1;

# 语句以分号结尾
set req.http.X-Custom = "value";

# 字符串使用双引号
set req.http.Host = "example.com";

# 正则表达式使用斜杠
if (req.url ~ "\.(css|js)$") {
    return (hash);
}

# 条件语句
if (req.method == "GET") {
    return (hash);
} elseif (req.method == "POST") {
    return (pass);
} else {
    return (synth(405, "Method Not Allowed"));
}

2.4 数据类型 #

类型 说明 示例
STRING 字符串 “hello”
INT 整数 3600
DURATION 时间间隔 1h, 30m, 60s
IP IP地址 “192.168.1.1”
BOOL 布尔值 true, false
REGEX 正则表达式 “.css$”
HEADER HTTP头 req.http.Host

2.5 运算符 #

vcl
# 比较运算符
==  # 等于
!=  # 不等于
<   # 小于
>   # 大于
<=  # 小于等于
>=  # 大于等于

# 逻辑运算符
&&  # 与
||  # 或
!   # 非

# 正则匹配
~   # 匹配
!~  # 不匹配

三、后端配置 #

3.1 基本后端定义 #

vcl
vcl 4.1;

backend default {
    .host = "127.0.0.1";
    .port = "8080";
}

3.2 后端参数详解 #

vcl
backend default {
    # 必需参数
    .host = "127.0.0.1";           # 后端主机地址
    .port = "8080";                 # 后端端口
    
    # 可选参数
    .host_header = "example.com";   # Host头
    .connect_timeout = 5s;          # 连接超时
    .first_byte_timeout = 90s;      # 首字节超时
    .between_bytes_timeout = 2s;    # 字节间超时
    .max_connections = 300;         # 最大连接数
    .proxy_header = 1;              # PROXY协议版本
}

3.3 多后端配置 #

vcl
backend static {
    .host = "192.168.1.10";
    .port = "80";
}

backend api {
    .host = "192.168.1.20";
    .port = "8080";
}

sub vcl_recv {
    if (req.url ~ "^/api/") {
        set req.backend_hint = api;
    } else {
        set req.backend_hint = static;
    }
}

四、ACL配置 #

4.1 定义ACL #

vcl
acl purge {
    "localhost";
    "192.168.1.0"/24;
    !"192.168.1.100";
}

acl admin {
    "10.0.0.0"/8;
}

4.2 使用ACL #

vcl
sub vcl_recv {
    if (req.method == "PURGE") {
        if (!client.ip ~ purge) {
            return (synth(405, "Not allowed."));
        }
        return (purge);
    }
}

五、子程序详解 #

5.1 子程序概览 #

子程序 触发时机 主要用途
vcl_init VCL加载时 初始化VMOD
vcl_recv 接收请求 请求处理、路由
vcl_pipe 管道模式 直接转发
vcl_pass 跳过缓存 直接请求后端
vcl_hash 计算缓存键 自定义缓存键
vcl_hit 缓存命中 处理命中响应
vcl_miss 缓存未命中 处理未命中请求
vcl_backend_fetch 请求后端 修改后端请求
vcl_backend_response 后端响应 处理后端响应
vcl_backend_error 后端错误 处理后端错误
vcl_deliver 返回响应 修改返回响应
vcl_synth 合成响应 自定义错误页面
vcl_fini VCL卸载时 清理资源

5.2 vcl_recv #

vcl
sub vcl_recv {
    # 标准化请求方法
    if (req.method != "GET" &&
        req.method != "HEAD" &&
        req.method != "PUT" &&
        req.method != "POST" &&
        req.method != "TRACE" &&
        req.method != "OPTIONS" &&
        req.method != "DELETE") {
        return (pipe);
    }
    
    # 非GET/HEAD请求不缓存
    if (req.method != "GET" && req.method != "HEAD") {
        return (pass);
    }
    
    # 移除Cookie以缓存静态资源
    if (req.url ~ "\.(css|js|png|gif|jpg|jpeg|ico|svg|woff|woff2)$") {
        unset req.http.Cookie;
        return (hash);
    }
    
    # 带Cookie的请求不缓存
    if (req.http.Cookie) {
        return (pass);
    }
    
    return (hash);
}

5.3 vcl_backend_response #

vcl
sub vcl_backend_response {
    # 设置缓存时间
    if (beresp.ttl <= 0s) {
        set beresp.ttl = 5m;
    }
    
    # 静态资源缓存更长时间
    if (bereq.url ~ "\.(css|js|png|gif|jpg|jpeg|ico|svg)$") {
        set beresp.ttl = 1d;
        unset beresp.http.Set-Cookie;
    }
    
    # 动态内容短缓存
    if (beresp.http.Content-Type ~ "text/html") {
        set beresp.ttl = 5m;
    }
    
    # 不缓存带Set-Cookie的响应
    if (beresp.http.Set-Cookie) {
        set beresp.uncacheable = true;
        set beresp.ttl = 0s;
    }
}

5.4 vcl_deliver #

vcl
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";
    }
    
    # 移除敏感头
    unset resp.http.X-Powered-By;
    unset resp.http.Server;
    
    # 添加调试信息
    if (req.http.X-Debug) {
        set resp.http.X-Varnish-Debug = "enabled";
    }
}

六、内置变量 #

6.1 请求变量 (req.*) #

变量 说明
req.url 请求URL
req.method 请求方法
req.http.* 请求头
req.proto HTTP协议版本
req.restarts 重启次数
req.xid 请求ID

6.2 后端请求变量 (bereq.*) #

变量 说明
bereq.url 后端请求URL
bereq.method 后端请求方法
bereq.http.* 后端请求头
bereq.connect_timeout 连接超时
bereq.first_byte_timeout 首字节超时

6.3 后端响应变量 (beresp.*) #

变量 说明
beresp.status 响应状态码
beresp.http.* 响应头
beresp.ttl 缓存TTL
beresp.grace 宽限时间
beresp.uncacheable 是否不可缓存

6.4 响应变量 (resp.*) #

变量 说明
resp.status 响应状态码
resp.http.* 响应头
resp.proto HTTP协议版本

6.5 对象变量 (obj.*) #

变量 说明
obj.status 对象状态码
obj.http.* 对象头
obj.ttl 对象TTL
obj.hits 命中次数
obj.grace 宽限时间

6.6 客户端变量 (client.*) #

叱量 说明
client.ip 客户端IP
client.identity 客户端标识

七、返回状态 #

7.1 vcl_recv返回值 #

返回值 说明
hash 计算缓存键,查找缓存
pass 跳过缓存,直接请求后端
pipe 管道模式,直接转发
purge 清除缓存
synth 返回合成响应
vcl 切换到其他VCL

7.2 vcl_backend_response返回值 #

返回值 说明
deliver 缓存并返回响应
retry 重试后端请求
abandon 放弃请求

7.3 vcl_deliver返回值 #

返回值 说明
deliver 返回响应
retry 重试

八、启动参数配置 #

8.1 存储配置 #

bash
# 内存存储
-s malloc,1G

# 文件存储
-s file,/var/lib/varnish/storage.bin,2G

# 混合存储
-s malloc,512m -s file,/var/lib/varnish/storage.bin,1G

存储参数说明:

参数 说明
malloc 内存存储
file 文件映射存储
大小 支持K/M/G单位

8.2 线程配置 #

bash
# 线程池配置
-p thread_pool_min=50
-p thread_pool_max=500
-p thread_pool_timeout=300
-p thread_pools=2

线程参数说明:

参数 默认值 说明
thread_pools 2 线程池数量
thread_pool_min 100 最小线程数
thread_pool_max 5000 最大线程数
thread_pool_timeout 300 空闲线程超时

8.3 内存配置 #

bash
# 工作区内存
-p http_resp_size=64k
-p http_req_size=32k
-p workspace_backend=64k
-p workspace_client=64k

8.4 超时配置 #

bash
# 连接超时
-p connect_timeout=3.5
-p first_byte_timeout=60
-p between_bytes_timeout=60

九、运行时参数 #

9.1 查看参数 #

bash
# 查看所有参数
varnishadm param.show

# 查看特定参数
varnishadm param.show thread_pool_max

# 查看参数说明
varnishadm param.show -l thread_pool_max

9.2 动态修改参数 #

bash
# 修改参数
varnishadm param.set thread_pool_max 1000

# 修改超时
varnishadm param.set connect_timeout 5

9.3 常用参数 #

参数 默认值 说明
default_ttl 120 默认缓存时间
default_grace 10 默认宽限时间
default_keep 0 默认保持时间
max_restarts 4 最大重启次数
max_retries 4 最大重试次数
send_timeout 600 发送超时
idle_send_timeout 60 空闲发送超时

十、完整配置示例 #

10.1 基础配置 #

vcl
vcl 4.1;

import std;

# 后端定义
backend default {
    .host = "127.0.0.1";
    .port = "8080";
    .connect_timeout = 5s;
    .first_byte_timeout = 90s;
    .between_bytes_timeout = 2s;
    .max_connections = 300;
}

# ACL定义
acl purge {
    "localhost";
    "192.168.1.0"/24;
}

# 初始化
sub vcl_init {
    # VMOD初始化
}

# 请求处理
sub vcl_recv {
    # PURGE请求处理
    if (req.method == "PURGE") {
        if (!client.ip ~ purge) {
            return (synth(405, "Not allowed."));
        }
        return (purge);
    }
    
    # BAN请求处理
    if (req.method == "BAN") {
        if (!client.ip ~ purge) {
            return (synth(405, "Not allowed."));
        }
        ban("req.url ~ " + req.url);
        return (synth(200, "Banned."));
    }
    
    # 非GET/HEAD请求
    if (req.method != "GET" && req.method != "HEAD") {
        return (pass);
    }
    
    # 移除静态资源的Cookie
    if (req.url ~ "\.(css|js|png|gif|jpg|jpeg|ico|svg|woff|woff2)$") {
        unset req.http.Cookie;
        return (hash);
    }
    
    # 健康检查
    if (req.url == "/healthcheck") {
        return (synth(200, "OK"));
    }
    
    return (hash);
}

# 缓存键计算
sub vcl_hash {
    hash_data(req.url);
    if (req.http.Host) {
        hash_data(req.http.Host);
    }
    return (lookup);
}

# 缓存命中
sub vcl_hit {
    return (deliver);
}

# 缓存未命中
sub vcl_miss {
    return (fetch);
}

# 后端响应处理
sub vcl_backend_response {
    # 设置默认TTL
    if (beresp.ttl <= 0s) {
        set beresp.ttl = 5m;
    }
    
    # 静态资源长缓存
    if (bereq.url ~ "\.(css|js|png|gif|jpg|jpeg|ico|svg|woff|woff2)$") {
        set beresp.ttl = 1d;
        unset beresp.http.Set-Cookie;
    }
    
    # 不缓存带Set-Cookie的响应
    if (beresp.http.Set-Cookie) {
        set beresp.uncacheable = true;
        set beresp.ttl = 0s;
    }
    
    # 设置宽限时间
    set beresp.grace = 1h;
}

# 响应处理
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";
    }
    
    # 移除敏感头
    unset resp.http.X-Powered-By;
    unset resp.http.Via;
}

# 合成响应
sub vcl_synth {
    set resp.http.Content-Type = "text/html; charset=utf-8";
    synthetic({"<!DOCTYPE html>
<html>
<head><title>"} + resp.status + " " + resp.reason + {"</title></head>
<body>
<h1>"} + resp.status + " " + resp.reason + {"</h1>
<p>"} + resp.reason + {"</p>
</body>
</html>
"});
    return (deliver);
}

十一、配置管理 #

11.1 加载新配置 #

bash
# 加载新VCL
varnishadm vcl.load new_config /etc/varnish/default.vcl

# 使用新VCL
varnishadm vcl.use new_config

# 查看VCL列表
varnishadm vcl.list

11.2 热重载 #

bash
# 使用varnishreload脚本
varnishreload

# 或手动操作
varnishadm vcl.load reload_$(date +%s) /etc/varnish/default.vcl
varnishadm vcl.use reload_$(date +%s)

11.3 配置回滚 #

bash
# 查看VCL列表
varnishadm vcl.list

# 回滚到旧配置
varnishadm vcl.use old_config_name

# 删除VCL
varnishadm vcl.discard unused_config

十二、总结 #

本章我们学习了:

  1. 配置文件结构:default.vcl、secret、varnish.params
  2. VCL语法基础:版本声明、注释、数据类型、运算符
  3. 后端配置:单后端、多后端、参数详解
  4. ACL配置:访问控制列表定义和使用
  5. 子程序详解:各子程序的用途和返回值
  6. 内置变量:请求、响应、对象等变量
  7. 启动参数:存储、线程、内存、超时配置
  8. 配置管理:加载、重载、回滚操作

掌握配置基础后,让我们进入下一章,学习Varnish的基本命令!

最后更新:2026-03-28