Varnish 是一款高性能的 HTTP 加速器(HTTP Accelerator),专为提升 Web 应用的速度和可扩展性而设计。它本质上是一个 反向代理缓存服务器,通过缓存静态和动态内容,大幅减少后端服务器(如 Apache、Nginx)的负载,提升用户访问速度。
安装varnish

1 2 3 4 5 6 7
| hostnamectl set-hostname varnish && bash
yum -y install varnish yum -y install varnish-docs systemctl enable varnish --now systemctl enable varnishncsa.service --now
|
测试日志
1 2 3 4 5
| curl localhost:80
tail -f /var/log/varnish/varnishncsa.log ::1 - - [10/Apr/2025:18:22:10 +0800] "GET http://localhost/ HTTP/1.1" 503 278 "-" "curl/7.76.1"
|
varnishd命令行配置
varnish有两个可配置的方式
- varnishd命令行配置工具
- /etc/varnish/default.vcl配置文件
varnishd配置参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| varnishd是一个守护进程
查看varnish的service文件就可以看出来 cat /usr/lib/systemd/system/varnish.service
... ExecStart=/usr/sbin/varnishd -a :6081 -f /etc/varnish/default.vcl -s malloc,256m ExecReload=/usr/sbin/varnishreload ...
可以看到启动命令是 varnishd -a :6081 -f /etc/varnish/default.vcl -s malloc,256m
varnishd -h查看帮助
|
参数 |
说明 |
示例 |
-a |
指定监听地址和端口(客户端访问入口),支持多协议(HTTP/HTTPS)。 |
-a :80(监听所有 IP 的 80 端口) |
-a 192.168.1.10:8080,PROXY(启用 PROXY 协议支持) |
|
|
-T |
指定管理接口(CLI)地址和端口,用于动态配置和监控。 |
-T 127.0.0.1:6082(本地管理端口) |
-f |
指定 VCL 配置文件路径,Varnish 启动时加载该配置。 |
-f /etc/varnish/default.vcl |
-s |
定义缓存存储后端(存储类型和大小),支持多种存储引擎。 |
-s malloc,1G(内存分配 1GB) |
-s file,/var/lib/varnish/storage.bin,10G(文件存储) |
|
|
-n |
指定工作目录(日志、PID 文件存放路径)。 |
-n /var/lib/varnish |
修改varnishd配置
正常服务器端口都是80对吧,也就是外部通过http或https访问它所认为的web后端时,会使用80或443端口,但varnishd默认使用的是6082端口,这怎么办呢?
创建一个/etc/system/varnish.service.d/httpport.conf:
子配置文件(drop-in 文件)可以覆盖父 Service 配置文件(主单元文件)中的相同字段。这是 systemd 设计中的一个核心特性,允许用户在不直接修改原始服务文件的情况下,通过添加或覆盖特定配置项来自定义服务行为。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| mkdir /etc/systemd/system/varnish.service.d cat > /etc/systemd/system/varnish.service.d/httpport.conf <<EOF [Service] ExecStart= ExecStart=/usr/sbin/varnishd -a :80 -f /etc/varnish/default.vcl -s malloc,256m EOF
systemctl daemon-reload systemctl restart varnish firewall-cmd --add-service=http firewall-cmd --add-service=http --permanent setenforce 0
netstat -tunlp | grep var | grep tcp6 -v tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 4950/varnishd tcp 0 0 127.0.0.1:35427 0.0.0.0:* LISTEN 4950/varnishd
可以看到已经在监听80端口了
|
为什么不直接修改/usr/lib/systemd/system/varnish.service?
因为如果varnishd更新了,那么这个service文件也会被覆盖掉
配置文件VCL
VCL(Varnish Configuration Language)是 Varnish HTTP 缓存服务器的核心配置语言,用于定义请求处理逻辑(如缓存规则、后端路由、流量过滤等)。它通过一系列“子例程”(Subroutines)控制 Varnish 对 HTTP 请求和响应的处理流程,支持高度灵活的缓存策略定制。
VCL 代码在加载时会被 编译为 C 语言代码,再编译成动态库供 Varnish 使用,因此性能极高。
VCL阶段
VCL 通过预定义的子例程定义处理流程,每个子例程在不同阶段触发:
子例程 |
触发时机 |
典型用途 |
vcl_recv |
客户端请求到达时 |
决定是否缓存、修改请求头、选择后端服务器 |
vcl_backend_fetch |
向后端服务器发起请求前 |
修改向后端发送的请求(如添加认证头) |
vcl_backend_response |
收到后端响应后 |
控制缓存策略(如缓存时间、缓存键)、修改响应头 |
vcl_deliver |
将响应返回给客户端前 |
添加调试头(如 X-Cache: HIT/MISS)、记录日志 |
vcl_hash |
生成缓存键时 |
自定义缓存键(如包含用户 Cookie) |
vcl_hit/vcl_miss |
缓存命中或未命中时 |
特殊处理(如命中后刷新缓存) |
允许刷新缓存
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| acl purge_allow_list { "localhost"; "10.163.2.200"; }
sub vcl_recv { if (req.method == "PURGE") { if (client.ip !~ purge_allow_list) { return (synth(405, "Not Allowed")); } return (purge); } }
|
缓存静态文件,并绕过动态缓存
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| sub vcl_recv { if (req.url ~ "\.(jpg|jpeg|png|gif|css|js|webp)$") { unset req.http.Cookie; return (hash); } if (req.method == "GET" || req.method == "HEAD") { return (hash); }
if (req.url ~ "^/api/" || req.url ~ "^/dynamic/") { return (pass); } return (pass); }
|
后端配置
后端服务器的ip配置略过
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| 只下载rpm包 yum -y --downloadonly --downloaddir=/root/httpd install httpd ls httpd/ apr-1.7.0-12.el9.x86_64.rpm httpd-core-2.4.62-4.el9.x86_64.rpm apr-util-1.6.1-23.el9.x86_64.rpm httpd-filesystem-2.4.62-4.el9.noarch.rpm apr-util-bdb-1.6.1-23.el9.x86_64.rpm httpd-tools-2.4.62-4.el9.x86_64.rpm apr-util-openssl-1.6.1-23.el9.x86_64.rpm mailcap-2.1.49-5.el9.noarch.rpm centos-logos-httpd-90.8-2.el9.noarch.rpm mod_http2-2.0.26-4.el9.x86_64.rpm httpd-2.4.62-4.el9.x86_64.rpm mod_lua-2.4.62-4.el9.x86_64.rpm
scp -r httpd 1.1.1.1:~ scp -r httpd 1.1.1.2:~ scp -r httpd 1.1.1.3:~ ssh 1.1.1.1 "rpm -vih httpd/*" ssh 1.1.1.2 "rpm -vih httpd/*" ssh 1.1.1.3 "rpm -vih httpd/*"
ssh 1.1.1.1 "echo 'wangsheng-1' > /var/www/html/index.html && sed -i 's/^Listen.*/Listen 8080/g' /etc/httpd/conf/httpd.conf && systemctl enable httpd --now" ssh 1.1.1.2 "echo 'wangsheng-2' > /var/www/html/index.html && sed -i 's/^Listen.*/Listen 8080/g' /etc/httpd/conf/httpd.conf && systemctl enable httpd --now" ssh 1.1.1.3 "echo 'wangsheng-3' > /var/www/html/index.html && sed -i 's/^Listen.*/Listen 8080/g' /etc/httpd/conf/httpd.conf && systemctl enable httpd --now" ssh 1.1.1.1 "systemctl restart httpd && systemctl disable firewalld --now" ssh 1.1.1.2 "systemctl restart httpd && systemctl disable firewalld --now" ssh 1.1.1.3 "systemctl restart httpd && systemctl disable firewalld --now"
vim /etc/varnish/default.vcl backend default { .host = "1.1.1.1"; .port = "8080"; } systemctl restart varnish
curl 1.1.1.1:8080 curl localhost wangsheng 可见已经将本地80端口的流量代理到了后端的8080端口
curl localhost curl localhost curl localhost curl localhost curl localhost curl localhost
后续的访问都已经被缓存了 默认情况下: Varnish 缓存命中时,后端服务器不会记录请求日志。 cat /var/log/varnish/varnishncsa.log ::1 - - [10/Apr/2025:20:28:18 +0800] "GET http://localhost/ HTTP/1.1" 200 10 "-" "curl/7.76.1" ::1 - - [10/Apr/2025:20:28:24 +0800] "GET http://localhost/ HTTP/1.1" 200 10 "-" "curl/7.76.1" 192.168.10.254 - - [10/Apr/2025:20:31:13 +0800] "GET http://10.163.2.100/ HTTP/1.1" 200 10 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36 Edg/133.0.0.0" 192.168.10.254 - - [10/Apr/2025:20:31:13 +0800] "GET http://10.163.2.100/favicon.ico HTTP/1.1" 404 196 "http://10.163.2.100/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36 Edg/133.0.0.0" 192.168.10.254 - - [10/Apr/2025:20:31:16 +0800] "GET http://10.163.2.100/ HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36 Edg/133.0.0.0"
varnishadm 'ban req.url == /index.html'
varnishadm 'ban req.url ~ .*'
|