Varnish 4.0.3详细配置

2023-12-13 09:38
文章标签 配置 详细 4.0 varnish

本文主要是介绍Varnish 4.0.3详细配置,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

最近在折腾varnish 4.0,话说从3.0到4.0变化挺大的,许多配置做了调整

对比Varnish 3.x的主要改进点
(1)、完全支持流对象;
(2)、可后台获取失效的对象,即Client/backend分离;
(3)、新的vanishlog查询语言,允许对请求进行自动分组;
(4)、复杂的请求时间戳和字节计数;
(5)、安全方面的提升;


涉及VCL语法的改变点
(1)、vcl配置文件需明确指定版本:即在vcl文件的第一行写上 vcl 4.0;
(2)、vcl_fetch函数被vcl_backend_response代替,且req.*不再适用vcl_backend_response;
(3)、后端源服务器组director成为varnish模块,需import directors后再在vcl_init子例程中定义;
(4)、自定义的子例程(即一个sub)不能以vcl_开头,调用使用call sub_name;
(5)、error()函数被synth()替代;
(6)、return(lookup)被return(hash)替代;
(7)、使用beresp.uncacheable创建hit_for_pss对象;
(8)、变量req.backend.healty被std.healthy(req.backend)替代;
(9)、变量req.backend被req.backend_hint替代;
(10)、关键字remove被unset替代;

详细可以参考:

https://www.varnish-cache.org/docs/4.0/whats-new/upgrading.html


工作流程

wKioL1VeCY-DPKO0AAJMe9Ky6sI343.jpg

Varnish 分为 master 进程和 child 进程:
Master 进程读入存储配置文件,调用合适的存储类型,然后创建 / 读入相应大小的缓存文件,接着 master 初始化管理该存储空间的结构体,然后 fork 并监控 child 进程;

Child 进程在主线程的初始化的过程中,将前面打开的存储文件整个 mmap 到内存中,此时创建并初始化空闲结构体,挂到存储管理结构体,以待分配;

对外管理接口分为3种,分别是命令行接口、Telnet接口和Web接口;

同时在运行过程中修改的配置,可以由VCL编译器编译成C语言,并组织成共享对象(Shared Object)交由Child进程加载使用;

wKioL1VeCjXQzfqpAAGwhfW_hms381.jpg

Child 进程分配若干线程进行工作,主要包括一些管理线程和很多 worker 线程,可分为:
Accept线程:接受请求,将请求挂在overflow队列上;
Work线程:有多个,负责从overflow队列上摘除请求,对请求进行处理,直到完成,然后处理下一个请求;
Epoll线程:一个请求处理称为一个session,在session周期内,处理完请求后,会交给Epoll处理,监听是否还有事件发生;
Expire线程:对于缓存的object,根据过期时间,组织成二叉堆,该线程周期检查该堆的根,处理过期的文件,对过期的数据进行删除或重取操作;


请求处理流程

wKioL1VeC6nTO12hAALZCRVU5rE198.jpg

 

Varnish 处理 HTTP 请求的过程如下
Receive 状态(vcl_recv):也就是请求处理的入口状态,根据 VCL 规则判断该请求应该 pass(vcl_pass)或是 pipe(vcl_pipe),还是进入 lookup(本地查询);
Lookup 状态:进入该状态后,会在 hash 表中查找数据,若找到,则进入 hit(vcl_hit)状态,否则进入 miss(vcl_miss)状态;
Pass(vcl_pass)状态:在此状态下,会直接进入后端请求,即进入 fetch(vcl_fetch)状态;
Fetch(vcl_fetch)状态:在 fetch 状态下,对请求进行后端获取,发送请求,获得数据,并根据设置进行本地存储;
Deliver(vcl_deliver)状态:将获取到的数据发给客户端,然后完成本次请求;

注:Varnish4中在vcl_fetch部分略有出入,已独立为vcl_backend_fetch和vcl_backend_response 2个函数;

内置函数(也叫子例程)
vcl_recv:用于接收和处理请求;当请求到达并成功接收后被调用,通过判断请求的数据来决定如何处理请求;
vcl_pipe:此函数在进入pipe模式时被调用,用于将请求直接传递至后端主机,并将后端响应原样返回客户端;
vcl_pass:此函数在进入pass模式时被调用,用于将请求直接传递至后端主机,但后端主机的响应并不缓存直接返回客户端;
vcl_hit:在执行 lookup 指令后,在缓存中找到请求的内容后将自动调用该函数;
vcl_miss:在执行 lookup 指令后,在缓存中没有找到请求的内容时自动调用该方法,此函数可用于判断是否需要从后端服务器获取内容;
vcl_hash:在vcl_recv调用后为请求创建一个hash值时,调用此函数;此hash值将作为varnish中搜索缓存对象的key;
vcl_purge:pruge操作执行后调用此函数,可用于构建一个响应;
vcl_deliver:将在缓存中找到请求的内容发送给客户端前调用此方法;
vcl_backend_fetch:向后端主机发送请求前,调用此函数,可修改发往后端的请求;
vcl_backend_response:获得后端主机的响应后,可调用此函数;
vcl_backend_error:当从后端主机获取源文件失败时,调用此函数;
vcl_init:VCL加载时调用此函数,经常用于初始化varnish模块(VMODs)
vcl_fini:当所有请求都离开当前VCL,且当前VCL被弃用时,调用此函数,经常用于清理varnish模块;


以上内容为在他人基础上学习总结而来,并非全部原创,望多多指教

废话就不多说了,以下是我目前整理出来的配置,有些参数还需要进一优化调整:

1、后端服务器健康检查

# vim /etc/varnish/health_check.vcl

1
2
3
4
5
6
7
8
9
10
11
12
probe backend_healthcheck {
     .interval = 5s;
     .timeout = 3s;
     .window = 10;
     .threshold = 8;
     
     .request =
     "GET /favicon.ico HTTP/1.1"
     "Host: www.xxx.com"
     "Connection: close"
     "Accept-Encoding: foo/bar";
}

2、后端服务器地址池配置

# vim /etc/varnish/backends.vcl

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
import directors;
include "health_check.vcl";
backend d102_app_07 {
     .host = "10.0.11.145";
     .port = "80";
     
     .first_byte_timeout = 9s;
     .connect_timeout = 3s;
     .between_bytes_timeout = 1s;
     
     .probe = backend_healthcheck;
}
backend d102_app_08 {
     .host = "10.0.11.146";
     .port = "80";
     
     .first_byte_timeout = 9s;
     .connect_timeout = 3s;
     .between_bytes_timeout = 1s;
     
     .probe = backend_healthcheck;
}
sub vcl_init {
     new web = directors.random();
     
     web.add_backend(d102_app_07, 1);
     web.add_backend(d102_app_08, 1);
}

3、缓存规则主配置

# vim /etc/varnish/default.vcl

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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
vcl 4.0;
import std;
include "backends.vcl";
acl allow_purge_cache {
     "127.0.0.1";
     "10.0.0.0"/8;
     "172.0.0.0"/8;
}
sub vcl_recv {
     if (req.method == "PURGE") {
         if (!client.ip ~ allow_purge_cache) {
             return (synth(405, "Not Allowed."));
         }
         
         return (purge);
     }
     
     set req.backend_hint = web.backend();
     
     if (req.url ~ "\.(php|asp|aspx|jsp|do|ashx|shtml)($|\?)") {
         return (pass);
     }
     
     if (req.url ~ "\.(css|js|html|htm|bmp|png|gif|jpg|jpeg|ico|gz|tgz|bz2|tbz|zip|rar|mp3|mp4|ogg|swf|flv)($|\?)") {
         unset req.http.cookie;
         return (hash);
     }
     
     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.http.Cache-Control ~ "(?i)no-cache") {
         if (!(req.http.Via || req.http.User-Agent ~ "(?i)bot" || req.http.X-Purge)) {
             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") {        
         return (pipe);
     }
     
     if (req.method != "GET" && req.method != "HEAD") {
         return (pass);
     }
     
     if (req.http.Authorization) {
         return (pass);
     }
     
     if (req.http.Accept-Encoding) {
         if (req.url ~ "\.(bmp|png|gif|jpg|jpeg|ico|gz|tgz|bz2|tbz|zip|rar|mp3|mp4|ogg|swf|flv)$") {
             unset req.http.Accept-Encoding;        
         } elseif (req.http.Accept-Encoding ~ "gzip") {
             set req.http.Accept-Encoding = "gzip";
         } elseif (req.http.Accept-Encoding ~ "deflate") {
             set req.http.Accept-Encoding = "deflate";
         } else {
             unset req.http.Accept-Encoding;
         }
     }
     
     if (req.http.Upgrade ~ "(?i)websocket") {
         return (pipe);
     }
     
     if (!std.healthy(req.backend_hint)) {
         unset req.http.Cookie;
     }
     
     if (req.http.x-pipe && req.restarts > 0) {
         unset req.http.x-pipe;
         return (pipe);
     }
     
     return (hash);
}
sub vcl_pipe {
     if (req.http.upgrade) {
         set bereq.http.upgrade = req.http.upgrade;
     }
     
     return (pipe);
}
sub vcl_pass {
     if (req.method == "PURGE") {
         return (synth(502, "PURGE on a passed object."));
     }
}
sub vcl_hash {
     hash_data(req.url);
     
     if (req.http.host) {
         hash_data(req.http.host);
     } else {
         hash_data(server.ip);
     }
     
     if (req.http.Cookie) {
         hash_data(req.http.Cookie);
     }
     
     if (req.http.Accept-Encoding ~ "gzip") {
         hash_data("gzip");
     } elseif (req.http.Accept-Encoding ~ "deflate") {
         hash_data("deflate");
     }
}
sub vcl_hit {
     if (req.method == "PURGE") {
         return (synth(200, "Purged."));
     }
     
     if (obj.ttl >= 0s) {
         return (deliver);
     }
     
     if (std.healthy(req.backend_hint)) {
         if (obj.ttl + 10s > 0s) {
             return (deliver);
         } else {
             return(fetch);
         }
     } else {
         if (obj.ttl + obj.grace > 0s) {
             return (deliver);
         } else {
             return (fetch);
         }
     }
     
     return (deliver);
}
sub vcl_miss {
     if (req.method == "PURGE") {
         return (synth(404, "Purged."));
     }
     
     return (fetch);
}
sub vcl_backend_response {
     set beresp.grace = 5m;
     
     set beresp.ttl = std.duration(regsub(beresp.http.Cache-Control, ".*s-maxage=([0-9]+).*", "\1") + "s", 0s);
     if (beresp.ttl > 0s) {
         unset beresp.http.Set-Cookie;
     }
     
     if (beresp.http.Set-Cookie) {
         set beresp.uncacheable = true;
         return (deliver);
     }
     
     if (beresp.http.Cache-Control && beresp.ttl > 0s) {
         set beresp.grace = 1m;
         unset beresp.http.Set-Cookie;
     }
     
     if (beresp.http.Content-Length ~ "[0-9]{8,}") {
         set bereq.http.x-pipe = "1";
         return (retry);
     }
     
     if (bereq.url ~ "\.(php|asp|aspx|jsp|do|ashx|shtml)($|\?)") {
         set beresp.uncacheable = true;
         return (deliver);
     }
     
     if (bereq.url ~ "\.(css|js|html|htm|bmp|png|gif|jpg|jpeg|ico|gz|tgz|bz2|tbz|zip|rar|mp3|mp4|ogg|swf|flv)($|\?)") {
         unset beresp.http.set-cookie;
     }
     
     if (bereq.url ~ "^[^?]*\.(mp[34]|rar|tar|tgz|gz|wav|zip|bz2|xz|7z|avi|mov|ogm|mpe?g|mk[av])(\?.*)?$") {
         unset beresp.http.set-cookie;
         set beresp.do_stream = true;
         set beresp.do_gzip = false;
     }
     
     if ((!beresp.http.Cache-Control && !beresp.http.Expires) || 
          beresp.http.Pragma ~ "no-cache" || 
          beresp.http.Cache-Control ~ "(no-cache|no-store|private)") {
         set beresp.ttl = 120s;
         set beresp.uncacheable = true;
         return (deliver);
     }
     
     if (beresp.ttl <= 0s || beresp.http.Set-Cookie || beresp.http.Vary == "*") {
         set beresp.ttl = 120s;
         set beresp.uncacheable = true;
         return (deliver);
     }
     
     if (bereq.url ~ "\.(css|js|html|htm|bmp|png|gif|jpg|jpeg|ico)($|\?)") {
         set beresp.ttl = 15m;
     } elseif (bereq.url ~ "\.(gz|tgz|bz2|tbz|zip|rar|mp3|mp4|ogg|swf|flv)($|\?)") {
         set beresp.ttl = 30m;
     } else {
         set beresp.ttl = 10m;
     }
     
     return (deliver);
}
sub vcl_purge {
     if (req.method != "PURGE") {
         set req.http.X-Purge = "Yes";
         return (restart);
     }
}
sub vcl_deliver {
     if (obj.hits > 0) {
         set resp.http.X-Cache = "HIT from " + req.http.host;
         set resp.http.X-Cache-Hits = obj.hits;
     } else {
         set resp.http.X-Cache = "MISS from " + req.http.host;
     }
     
     unset resp.http.X-Powered-By;
     unset resp.http.Server;
     
     unset resp.http.Via;
     unset resp.http.X-Varnish;
     
     unset resp.http.Age;
}
sub vcl_backend_error {
     if (beresp.status == 500 || 
         beresp.status == 501 || 
         beresp.status == 502 || 
         beresp.status == 503 || 
         beresp.status == 504) {
         return (retry);
     }
}
sub vcl_fini {
     return (ok);
}

4、启动参数配置

# vim /etc/sysconfig/varnish

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
NFILES=131072
MEMLOCK=25165824
NPROCS="unlimited"
RELOAD_VCL=1
VARNISH_VCL_CONF=/etc/varnish/default.vcl
VARNISH_LISTEN_ADDRESS=0.0.0.0
VARNISH_LISTEN_PORT=6081
VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1
VARNISH_ADMIN_LISTEN_PORT=6082
VARNISH_SECRET_FILE=/etc/varnish/secret
VARNISH_MIN_THREADS=240
VARNISH_MAX_THREADS=4800
VARNISH_THREAD_TIMEOUT=120
VARNISH_STORAGE_SIZE=24G
VARNISH_STORAGE="malloc,${VARNISH_STORAGE_SIZE}"
VARNISH_TTL=120
DAEMON_OPTS="-a ${VARNISH_LISTEN_ADDRESS}:${VARNISH_LISTEN_PORT} \
         -f ${VARNISH_VCL_CONF} \
         -T ${VARNISH_ADMIN_LISTEN_ADDRESS}:${VARNISH_ADMIN_LISTEN_PORT} \
         -t ${VARNISH_TTL} \
         -p thread_pools=24 \
         -p thread_pool_min=${VARNISH_MIN_THREADS} \
         -p thread_pool_max=${VARNISH_MAX_THREADS} \
         -p thread_pool_timeout=${VARNISH_THREAD_TIMEOUT} \
         -u varnish -g varnish \
         -S ${VARNISH_SECRET_FILE} \
         -s ${VARNISH_STORAGE} \
         -p timeout_idle=60 \
         -p timeout_linger=1 \
         -p http_resp_hdr_len=16k \
         -p http_max_hdr=256 \
         -p http_req_hdr_len=16k \
         -p lru_interval=120 \
         -p listen_depth=8192"

5、启动脚本调整

# vim /etc/init.d/varnish


exec="/usr/sbin/varnishd"
修改为
exec="/usr/bin/numactl --interleave all /usr/sbin/varnishd"

这篇关于Varnish 4.0.3详细配置的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/487976

相关文章

IntelliJ IDEA 中配置 Spring MVC 环境的详细步骤及问题解决

《IntelliJIDEA中配置SpringMVC环境的详细步骤及问题解决》:本文主要介绍IntelliJIDEA中配置SpringMVC环境的详细步骤及问题解决,本文分步骤结合实例给大... 目录步骤 1:创建 Maven Web 项目步骤 2:添加 Spring MVC 依赖1、保存后执行2、将新的依赖

SpringBoot基于配置实现短信服务策略的动态切换

《SpringBoot基于配置实现短信服务策略的动态切换》这篇文章主要为大家详细介绍了SpringBoot在接入多个短信服务商(如阿里云、腾讯云、华为云)后,如何根据配置或环境切换使用不同的服务商,需... 目录目标功能示例配置(application.yml)配置类绑定短信发送策略接口示例:阿里云 & 腾

如何为Yarn配置国内源的详细教程

《如何为Yarn配置国内源的详细教程》在使用Yarn进行项目开发时,由于网络原因,直接使用官方源可能会导致下载速度慢或连接失败,配置国内源可以显著提高包的下载速度和稳定性,本文将详细介绍如何为Yarn... 目录一、查询当前使用的镜像源二、设置国内源1. 设置为淘宝镜像源2. 设置为其他国内源三、还原为官方

最详细安装 PostgreSQL方法及常见问题解决

《最详细安装PostgreSQL方法及常见问题解决》:本文主要介绍最详细安装PostgreSQL方法及常见问题解决,介绍了在Windows系统上安装PostgreSQL及Linux系统上安装Po... 目录一、在 Windows 系统上安装 PostgreSQL1. 下载 PostgreSQL 安装包2.

CentOS7更改默认SSH端口与配置指南

《CentOS7更改默认SSH端口与配置指南》SSH是Linux服务器远程管理的核心工具,其默认监听端口为22,由于端口22众所周知,这也使得服务器容易受到自动化扫描和暴力破解攻击,本文将系统性地介绍... 目录引言为什么要更改 SSH 默认端口?步骤详解:如何更改 Centos 7 的 SSH 默认端口1

Maven的使用和配置国内源的保姆级教程

《Maven的使用和配置国内源的保姆级教程》Maven是⼀个项目管理工具,基于POM(ProjectObjectModel,项目对象模型)的概念,Maven可以通过一小段描述信息来管理项目的构建,报告... 目录1. 什么是Maven?2.创建⼀个Maven项目3.Maven 核心功能4.使用Maven H

SpringBoot多数据源配置完整指南

《SpringBoot多数据源配置完整指南》在复杂的企业应用中,经常需要连接多个数据库,SpringBoot提供了灵活的多数据源配置方式,以下是详细的实现方案,需要的朋友可以参考下... 目录一、基础多数据源配置1. 添加依赖2. 配置多个数据源3. 配置数据源Bean二、JPA多数据源配置1. 配置主数据

Spring 基于XML配置 bean管理 Bean-IOC的方法

《Spring基于XML配置bean管理Bean-IOC的方法》:本文主要介绍Spring基于XML配置bean管理Bean-IOC的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一... 目录一. spring学习的核心内容二. 基于 XML 配置 bean1. 通过类型来获取 bean2. 通过

MySql match against工具详细用法

《MySqlmatchagainst工具详细用法》在MySQL中,MATCH……AGAINST是全文索引(Full-Textindex)的查询语法,它允许你对文本进行高效的全文搜素,支持自然语言搜... 目录一、全文索引的基本概念二、创建全文索引三、自然语言搜索四、布尔搜索五、相关性排序六、全文索引的限制七

python中各种常见文件的读写操作与类型转换详细指南

《python中各种常见文件的读写操作与类型转换详细指南》这篇文章主要为大家详细介绍了python中各种常见文件(txt,xls,csv,sql,二进制文件)的读写操作与类型转换,感兴趣的小伙伴可以跟... 目录1.文件txt读写标准用法1.1写入文件1.2读取文件2. 二进制文件读取3. 大文件读取3.1