修改配置文件

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
vim /usr/local/varnish/default.vcl 
probe health {
.url = "/"; # 检查请求的url路径
.timeout = 3s; # 超时时间3s
.interval = 1s; # 访问间隔时间1s
.window = 5; # 维持5个窗口
.threshold = 3; # 5个窗口中至少3个是成功的
}
backend web1 { # 后端web集群
.host = "172.16.1.13";
.port = "80";
.probe = health; # 添加对本主机的健康检查
.max_connections = 100;
}

backend web2 { # 后端web集群
.host = "172.16.1.14";
.port = "80";
.probe = health; # 添加对本主机的健康检查
.max_connections = 100;
}
acl allow{ # 对于清除缓存的访问控制列表,只允许本地进行清除缓存
"127.0.0.1";
"localhost";
"172.16.1.12";
}
import directors; # 导入集群模块
sub vcl_init{ # 导入轮询模块
new back = directors.round_robin(); # 轮询方式为rr
back.add_backend(web1); # 轮询web1
back.add_backend(web2); # 轮询web2
}

sub vcl_recv{ # 数据请求模块
set req.backend_hint = back.backend(); # 如果后端站点健康检查为不健康,则屏蔽掉
if(req.method == "PURGE"){ # 如果数据请求的方法为PURGE的情况下
if(client.ip !~ allow){ # 如果客户机ip不在acl允许的访问控制列表中
return(synth(403,"NOT ALLOW")); # 则在主机头中返回状态码403,不允许
}
else{ # 反之(客户机ip在acl中)
return(purge); # 则清除缓存
}
}
if(req.http.host ~ "^img"){ # 如果请求的http协议的host以img开头
set req.backend_hint = web1; # 则调度到web1后端
}
if(req.http.host ~ "^www"){ # 如果请求的http协议的host以www开头
set req.backend_hint = web2; # 则调度到web2后端
}
if(req.url ~ "\.(php|asp|aspx|jsp|do)($|\?)"){ # 如果请求的url为动态数据
return(pass); # 则进入pass模块(去后端索取内容)
}
if(req.url ~ "\.(css|htm|html|png|gif|jpg)($|\?)"){ # 如果请求的url为静态数据
return(hash); # 则进入hash模块进行hash
}
if(req.method != "GET" &&
req.method != "PUT" &&
req.method != "POST" &&
req.method != "DELETE" &&
req.method != "HEAD"
){ # 如果请求的方法非正常
return(pipe); # 则直接到错误页面
}
if(req.method != "GET" && req.method != "HEAD"){ # 如果请求的方法是除了get和head以外的方法
return(pass); # 则进入到pass模块(去后端)
}
if(req.http.Authorization){ # 如果请求头部中存在认证
return(pass); # 则进入到pass模块(去后端)
}
if(req.http.Accept-Encoding){ # 如果浏览器支持编码
if(req.url ~ "\.(png|gif|jpg|jpeg|gz|)"){ # 如果请求的url中包含这些格式的内容
unset req.http.Accept-Encoding; # 则不进行压缩
}
elseif(req.http.Accept-Encoding ~ "gzip"){ # 如果浏览器支持的编码格式为gzip
set req.http.Accept-encoding = "gzip"; # 则使用gzip压缩
}
elseif(req.http.Accept-Encoding ~ "deflate"){ # 如果浏览器支持的编码格式为deflate
set req.http.Accept-Encoding = "deflate"; # 则使用zlib压缩
}
else{ # 否则
unset req.http.Accept-Encoding; # 不进行压缩
}
}
}
# 配置pipe模块
sub vcl_pipe{
return(pipe); # 进入到此模块的,直接退出
}
# 配置pass动态数据模块
sub vcl_pass{
return(fetch); # 进入到此模块的,去后端索取内容
}
# 配置hash静态数据模块
sub vcl_hash{
hash_data(req.url); # 进入到此模块的对url进行hash
if(req.http.host){ # 如果请求的主机头中存在host部分
hash_data(req.http.host); # 则对host进行hash
}
else{ # 如果不存在
hash_data(server.ip); # 则对ip进行hash
if(req.http.Accept-Encoding ~ "gzip"){ # 如果浏览器的编码为gzip
hash_data("gzip"); # 则对gzip文件进行hash
}
elseif(req.http.Accept-Encoding ~ "deflate"){ # 如果浏览器的编码为deflate
hash_data("deflate"); # 则对deflate进行hash
}
}
}
# 配置hit命中模块
sub vcl_hit{
return(deliver); # 进入到hit模块中,则直接返回客户端数据
}
# 配置miss未命中模块
sub vcl_miss{
return(fetch); # 进入到miss模块中,则进入后端获取内容
}
# 配置后端节点模块
sub vcl_backend_response{
if(bereq.url ~ "\.(php|asp|jsp|do)$"){ # 如果返回的url中带有这些后缀的(动态数据)
set beresp.uncacheable = true; # 不在本地进行缓存
}
if(bereq.url ~ "\.(css|js|html|png|gif)"){ # 如果返回的url中带有这些后缀的(静态数据)
set beresp.ttl = 15m; # 将内容在内存中缓存停留15分钟
}
if(bereq.url ~ "\.(gz|bz2|mp3)"){ # 如果返回的url中带有这些后缀的
set beresp.ttl = 30m; # 将内容在内存中缓存停留30分钟
}
return(deliver); # 其余的直接交给客户端
}
# 配置清除缓存的模块
sub vcl_purge{
return(synth(200,"success")); # 进入到purge模块的返回状态码200, 信息success
}
# 配置响应客户端
sub vcl_deliver{
if(obj.hits > 0){ # 如果缓存命中次数大于0
set resp.http.X-Cache = "hit"; # varnish返回给客户端的信息头部,新建一条hit
}
else{ # 反之
set resp.http.X-Cache = "miss"; # varnish返回给客户端的信息头部,新建一条miss
}
return(deliver); # 正常结束
}

检查文件语法并启动

1
2
3
varnishd -C -f /usr/local/varnish/default.vcl  # 检查语法
killall -9 varnishd # 如果之前启动过,需要先停掉服务
varnishd -f /usr/local/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
[root@localhost ~]# curl -I 172.16.1.12
HTTP/1.1 200 OK
Date: Sat, 08 Feb 2020 04:58:02 GMT
Server: Apache/2.4.6 (CentOS)
Last-Modified: Fri, 07 Feb 2020 15:21:52 GMT
ETag: "6-59dfdf301c530"
Content-Length: 6
Content-Type: text/html; charset=UTF-8
X-Varnish: 2
Age: 0
Via: 1.1 varnish-v4
X-Cache: miss # 第一次访问没有缓存,也就是没有命中,hit<0,返回miss
Accept-Ranges: bytes
Connection: keep-alive

[root@localhost ~]# curl -I 172.16.1.12
HTTP/1.1 200 OK
Date: Sat, 08 Feb 2020 04:58:02 GMT
Server: Apache/2.4.6 (CentOS)
Last-Modified: Fri, 07 Feb 2020 15:21:52 GMT
ETag: "6-59dfdf301c530"
Content-Length: 6
Content-Type: text/html; charset=UTF-8
X-Varnish: 32770 3
Age: 1
Via: 1.1 varnish-v4
X-Cache: hit # 第二次访问直接访问缓存,也就是命中,hit>0,返回hit
Accept-Ranges: bytes
Connection: keep-alive

访问

1
2
3
4
curl 172.16.1.12
welcome to WEB-One
curl 172.16.1.12
welcome to WEB-One

清除缓存

1
2
3
4
5
6
7
8
9
10
[root@localhost ~]# curl -I http://172.16.1.12 -X PURGE
HTTP/1.1 200 success # 返回success,清除成功
Date: Fri, 07 Feb 2020 05:18:16 GMT
Server: Varnish
X-Varnish: 32780
Content-Type: text/html; charset=utf-8
Retry-After: 5
Content-Length: 252
Accept-Ranges: bytes
Connection: keep-alive

访问

1
2
3
4
curl 172.16.1.12
welcome to WEB-Two
curl 172.16.1.12
welcome to WEB-Two