安装部署
安装服务
Rocky Linux 8 Varnish Cache 是6.0的版本
dnf install varnish -y
服务完整配置
vim /etc/varnish/default.vcl
vcl 4.0;
# 加载后端轮询模块
import directors;
#######################健康检查策略区域###########################
# 名为www_probe的健康检查策略
#probe admin_probe {
# .request =
# "GET / HTTP/1.1" # 健康检查url为/html/test.html 协议为http1.1
# "Host: _" # 访问的域名为www.xiaxiaodie.com
# "Connection: close"; # 检查完关闭连接
#其他参数 如 超时时间 检查间隔 等 均使用默认
#}
##################################################################
#######################配置后端区域################################
# www.cn2linux.com
backend admin_01 {
.host = "127.0.0.1";
.port = "80";
# .probe = admin_probe;
}
#默认后端
#backend default {
# .host = "1.1.1.1" ;
# .port = "80";
#}
###################################################################
# 配置后端集群事件
sub vcl_init {
# 后端集群有4种模式 random, round-robin, fallback, hash
# random 随机
# round-robin 轮询
# fallback 后备
# hash 固定后端 根据url(req.http.url) 或 用户cookie(req.http.cookie) 或 用户session(req.http.sticky)(这个还有其他要配合)
# 把backend_15 和 backend_16配置为轮询集群 取名为www_round_robin
new admin_round_robin = directors.round_robin();
admin_round_robin.add_backend(admin_01);
}
#定义允许清理缓存的IP
acl purge {
# For now, I'll only allow purges coming from localhost
"127.0.0.1";
"localhost";
}
# 请求入口 这里一般用作路由处理 判断是否读取缓存 和 指定该请求使用哪个后端
sub vcl_recv {
# 使用固定后端集群例子 使用名为www_hash的集群
if (req.http.host ~ "www.cn2linux.com") {
set req.backend_hint = admin_round_robin.backend(); # 根据用户的cookie来分配固定后端 可以指定其他分配规则
}
# 其他将使用default默认后端
# 把真实客户端IP传递给后端服务器 后端服务器日志使用X-Forwarded-For来接收
if (req.restarts == 0) {
if (req.http.X-Forwarded-For) {
set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip;
} else {
set req.http.X-Forwarded-For = client.ip;
}
}
# 匹配清理缓存的请求
if (req.method == "PURGE") {
# 如果发起请求的客户端IP 不是在acl purge里面定义的 就拒绝
if (!client.ip ~ purge) {
return (synth(405, "This IP is not allowed to send PURGE requests."));
}
# 是的话就执行清理
return (purge);
}
# 如果不是正常请求 就直接穿透没商量
if (req.method != "GET" &&
req.method != "HEAD" &&
req.method != "PUT" &&
req.method != "POST" &&
req.method != "TRACE" &&
req.method != "OPTIONS" &&
req.method != "PATCH" &&
req.method != "DELETE") {
/* Non-RFC2616 or CONNECT which is weird. */
return (pipe);
}
# 如果不是GET和HEAD就跳到pass 再确定是缓存还是穿透
if (req.method != "GET" && req.method != "HEAD") {
return (pass);
}
# 缓存通过上面所有判断的请求 (只剩下GET和HEAD了)
return (hash);
}
# pass事件
sub vcl_pass {
# 有fetch,synth or restart 3种模式. fetch模式下 全部都不会缓存
return (fetch);
}
# hash事件(缓存事件)
sub vcl_hash {
# 根据以下特征来判断请求的唯一性 并根据此特征来缓存请求的内容 特征为&关系
# 1. 请求的url
# 2. 请求的servername 如没有 就记录请求的服务器IP地址
# 3. 请求的cookie
hash_data(req.url);
if (req.http.host) {
hash_data(req.http.host);
} else {
hash_data(server.ip);
}
# 返回lookup , lookup不是一个事件(就是 并非指跳去sub vcl_lookup) 他是一个操作 他会检查有没有缓存 如没有 就会创建缓存
return (lookup);
}
# 缓存命中事件 在lookup操作后自动调用 官网文档说 如没必要 一般不需要修改
sub vcl_hit {
# 可以在这里添加判断事件(if) 可以返回 deliver restart synth 3个事件
# deliver 表示把缓存内容直接返回给用户
# restart 重新启动请求 不建议使用 超过重试次数会报错
# synth 返回状态码 和原因 语法:return(synth(status code,reason))
# 这里没有判断 所有缓存命中直接返回给用户
return (deliver);
}
# 缓存不命中事件 在lookup操作后自动调用 官网文档说 如没必要 一般不需要修改
sub vcl_miss {
if (req.url ~ "\.(mp4)(?=\?|&|$)" && req.http.Range ~ "bytes\=0\-$") {
unset req.http.Range;
}
# 此事件中 会默认给http请求加一个 X-Varnish 的header头 提示: nginx可以根据此header来判断是否来自varnish的请求(就不用起2个端口了)
# 要取消此header头 只需要在这里添加 unset bereq.http.x-varnish; 即可
# 这里所有不命中的缓存都去后端拿 没有其他操作 fetch表示从后端服务器拿取请求内容
return (fetch);
}
# 返回给用户的前一个事件 通常用于添加或删除header头
sub vcl_deliver {
# 例子
# set resp.http.* 用来添加header头 如 set resp.http.xiaxiaodie = "haha"; unset为删除
# set resp.status 用来设置返回状态 如 set resp.status = 404;
# obj.hits 会返回缓存命中次数 用于判断或赋值给header头
# req.restarts 会返回该请求经历restart事件次数 用户判断或赋值给header头
# 根据判断缓存时间来设置xiaxiaodie-Cache header头
if (obj.hits > 0) {
set resp.http.http_Cache = "cached";
} else {
set resp.http.http_Cache = "uncached";
}
#取消显示php框架版本的header头
unset resp.http.X-Powered-By;
#取消显示nginx版本、Via(来自varnish)等header头 为了安全
unset resp.http.Server;
unset resp.http.X-Drupal-Cache;
unset resp.http.Via;
unset resp.http.Link;
unset resp.http.X-Varnish;
#显示请求经历restarts事件的次数
set resp.http.restarts_count = req.restarts;
#显示该资源缓存的时间 单位秒
set resp.http.Age = resp.http.Age;
#显示该资源命中的次数
set resp.http.hit_count = obj.hits;
#取消显示Age 为了不和CDN冲突
unset resp.http.Age;
unset resp.http.vary;
#返回给用户
return (deliver);
}
#处理对后端返回结果的事件(设置缓存、移除cookie信息、设置header头等) 在fetch事件后自动调用
sub vcl_backend_response {
#后端返回如下错误状态码 则不缓存
if (beresp.status == 499 || beresp.status == 404 || beresp.status == 502) {
set beresp.uncacheable = true;
}
if (bereq.url ~ "\.(css|js)(\?|$)") {
# 如果请求是 CSS JS 则缓存 720 小时
set beresp.ttl = 720h;
unset beresp.http.Set-Cookie;
} elseif (bereq.url ~ "\.(ico|jpg|png|gif|bmp|apng|psd|woff2)(\?|$)") {
# 如果请求是 图片文件 则缓存 720 小时
set beresp.ttl = 720h;
unset beresp.http.Set-Cookie;
} elseif (bereq.url ~ "\.(mp3|mp4|avi|mkv|flv|vob|wmv|3gp)(\?|$)") {
# 如果请求是 视频流格式 则缓存 720 小时
set beresp.ttl = 720h;
unset beresp.http.Set-Cookie;
} elseif (bereq.url ~ "\.(htm|html)(\?|$)") {
# 如果请求是 静态页面 则缓存 720 小时
set beresp.ttl = 720h;
unset beresp.http.Set-Cookie;
} else {
# 其它则不缓存
set beresp.uncacheable = true;
}
#开启grace模式 表示当后端全挂掉后 即使缓存资源已过期(超过缓存时间) 也会把该资源返回给用户 资源最大有效时间为6小时
set beresp.grace = 6h;
#返回给用户
return (deliver);
}
配置启动服务环境变量及文件
在 Varnish 中,启动参数通常不是在 VCL 配置文件中设置的,而是在 Varnish 服务的启动脚本或配置文件中指定的。不过,您可以将这些参数单独放入一个配置文件中,然后在启动 Varnish 时引用这个文件。这样做的好处是使配置更加模块化和易于管理。
在基于 systemd 的系统上(例如最新版本的 Ubuntu、Debian、CentOS 等),这通常是通过编辑 Varnish 服务的 systemd 单元文件来实现的。
创建一个新的配置文件,例如 /etc/default/varnish
或 /etc/sysconfig/varnish
,取决于您的操作系统。
在文件中写入您的参数:
VARNISH_LISTEN_PORT=6081
VARNISH_ADMIN_LISTEN_ADDRESS=localhost
VARNISH_ADMIN_LISTEN_PORT=6082
VARNISH_VCL_CONF=/etc/varnish/default.vcl
VARNISH_SECRET_FILE=/etc/varnish/secret
VARNISH_STORAGE="malloc,256m"
VARNISH_THREAD_POOLS=2
VARNISH_THREAD_POOL_MIN=100
VARNISH_THREAD_POOL_MAX=5000
修改 systemd 单元文件,以引用这个新的配置文件。
编辑 /lib/systemd/system/varnish.service
,找到 ExecStart
行,并修改它以使用新的配置文件。例如:
EnvironmentFile=/etc/default/varnish
ExecStart=/usr/sbin/varnishd -a :${VARNISH_LISTEN_PORT} \
-T ${VARNISH_ADMIN_LISTEN_ADDRESS}:${VARNISH_ADMIN_LISTEN_PORT} \
-f ${VARNISH_VCL_CONF} \
-S ${VARNISH_SECRET_FILE} \
-s ${VARNISH_STORAGE} \
-p thread_pools=${VARNISH_THREAD_POOLS} \
-p thread_pool_min=${VARNISH_THREAD_POOL_MIN} \
-p thread_pool_max=${VARNISH_THREAD_POOL_MAX}
启动服务并设置开机自启
systemctl enable --now varnish
配置 Nginx 作为负载均衡器
额外补充,可不配置
在 Nginx 配置文件中, 设置一个上游服务器块,其中包含您的 Varnish 实例,并启用一致性哈希。在这个配置中,hash $request_uri consistent;
行确保基于请求 URI 的一致性哈希。这意味着相同 URI 的请求将始终被路由到同一个 Varnish 实例。
http {
upstream varnish_cluster {
hash $request_uri consistent;
server varnish_instance_1:80;
server varnish_instance_2:80;
# 添加更多的 Varnish 实例...
}
server {
listen 80;
location / {
proxy_pass http://varnish_cluster;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 可能需要的其他 proxy 设置...
}
}
}
评论区