目录
  1. 1. varnish
    1. 1.1. 引言
    2. 1.2. 安装部署
      1. 1.2.1. 源码安装
      2. 1.2.2. 从源安装(推荐)
    3. 1.3. 初步配置
    4. 1.4. 注意
    5. 1.5. 原理解析
    6. 1.6. 使用vcl编写配置
    7. 1.7. 测试
varnish安装与应用

varnish

引言

varnish是一款高性能的开源的方向代理服务器和http加速器。

安装部署

1
2
3
4
5
useradd  -s /sbin/nologin  varnish
mkdir /data/vanish/cache -pv
mkdir /data/vanish/log
chown -R varnish:varnish /data/vanish/cache/
chown -R varnish:varnish /data/vanish/log/

源码安装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
sudo yum install \
make \
autoconf \
automake \
jemalloc-devel \
libedit-devel \
libtool \
ncurses-devel \
pcre-devel \
pkgconfig \
python3-docutils \
python3-sphinx

yum install graphviz
yum install git

cd varnish
sh autogen.sh
sh configure
make
make test
make install

从源安装(推荐)

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
创建varn.repo
[varnishcache_varnish60lts]
name=varnishcache_varnish60lts
baseurl=https://packagecloud.io/varnishcache/varnish60lts/el/6/$basearch
repo_gpgcheck=1
gpgcheck=0
enabled=1
gpgkey=https://packagecloud.io/varnishcache/varnish60lts/gpgkey
sslverify=1
sslcacert=/etc/pki/tls/certs/ca-bundle.crt
metadata_expire=300

[varnishcache_varnish60lts-source]
name=varnishcache_varnish60lts-source
baseurl=https://packagecloud.io/varnishcache/varnish60lts/el/6/SRPMS
repo_gpgcheck=1
gpgcheck=0
enabled=1
gpgkey=https://packagecloud.io/varnishcache/varnish60lts/gpgkey
sslverify=1
sslcacert=/etc/pki/tls/certs/ca-bundle.crt
metadata_expire=300

yum clean all
yum makecache
yum install varnish

初步配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 开启服务
service varnish start
# 默认从rack-leen.top的80端口中拉取数据缓存 varnish可以定义几个backend,并将其加入负载均衡
/etc/varnish/default.vcl
backend default {
.host = "rack-leen.top";
.port = "80";
}

# 更改监听端口
# 原理: varnish相当于一堵墙,用户请求的时候是先经过varnish,如果其后是varnish代理用户拉取目标服务器的数据,因此用户访问的是varnish服务器
/etc/varnish/varnish.params
# 将监听端口改为需要访问的端口
VARNISH_LISTEN_PORT=6081

注意

varnish6.3依赖systemed python3

varnish默认只缓存get和head请求

原理解析

a
首先,varnish接收到访问请求(vcl_recv)
然后,有三个选项,(本地查询,直接pass和pipe) 默认本地查询

  • pipe,用户将请求直接传递至后端主机,在请求和返回的内容没有改变的情况下,将不变的内容返回给客户端,直到这个链接被关闭。
  • pass,直接拉取backend服务器数据。
  • 本地查询,查询varnish服务器中是否存在缓存
    如果有,则访问这个缓存,之后有两个选项,是否将缓存发送到客户端,是则直接将缓存发送(deliver)给客户端,如果不是则进入pass状态,然后拉取backend服务器数据。
    如果没有,直接拉取backend服务器数据。

拉取(fetch)backend中的服务器数据。然后判断是否缓存,如果不缓存,直接将服务器数据传给客户端,如果缓存,则先将数据缓存到varnish,再发送给客户端。

使用vcl编写配置

编写/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
import directors;
import std ;

# 访问控制,清理varnish缓存的角色
acl purge {
"127.0.0.1";
"localhost";
}

# 需要请求的目标服务器
backend default {
.host = "";
.port = "";
}

backend nginx1 {
.host = "";
.port = "";
}

backend nginx2 {
.host = "";
.port = "";
}

# 刚开始初始化的方法
sub vcl_init {
new bar = directors.round_robin(); # 创建负载均衡的服务器组,采用轮询方式
bar.add_backend(nginx1) ;
bar.add_backend(nginx2) ;
}

# 接收方法
sub vcl_recv {
set req.backend_hint = bar.backend() ; # 接收请求命中的服务器是bar组中的服务器

if (req.method == "PURGE") { # 清理缓存
if (!client.ip ~ purge) { # 如果不是本机,不能清理缓存
return (synth(405 , "This IP is not allowed to send PURGE requests."));
}

return (purge) ;
}

# 如果不是这些方法,就使用pipe模式,直接与服务器连接,直到pipe连接关闭
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) ;
}

# 如果请求方法不是GET和HEAD,就直接访问服务器拉取数据,因为GET和HEAD访问的比较频繁,而且获取的内容相同,需要做缓存
if (req.method != "GET" && req.method != "HEAD") {
return (pass) ;
}

# 如果请求的是大文件,就不要把它放到cookie里面了
if (req.url ~ "^[^?]*\.(bmp|bz2|css|doc|eot|flv|gif|gz|ico|jpeg|jpg|js|less|pdf|png|rtf|swf|txt|woff|xml)(\?.*)?$") {
unset req.http.Cookie ;
# 先本地查询
return (hash) ;
}

# 没有足够权限获取缓存,就直接拉取
if (req.http.Authorization) {
return (pass) ;
}

# 如果是上诉其他情况,请求之后,就进入本地查询
return (hash) ;
}

# 管道直连,直到pipe关闭,连接才关闭
sub vcl_pipe {
return (pipe) ;
}

# 将请求进行hash算法,得到唯一值
sub vcl_hash {
hash_data(req.url); # 获取请求url的hash
if (req.http.host) { # 如果请求的是域名
hash_data(req.http.host);
}else { # 否则直接使用主机ip
hash_data(server.ip) ;
}
# 如果存在cookie
if (req.http.Cookie) {
hash_data(req.http.Cookie) ;
}
}

# 命中varnish 中的缓存
sub vcl_hit {
return (deliver) ; # 命中之后就直接返回给客户端
}

sub vcl_miss {
std,log("url miss! the url= " + req.url) ; # 输出未命中的url
return (fetch) ; # 如果没有缓存,就拉取服务器的数据
}

# 这个函数可以设置缓存生命周期
sub vcl_backend_response {
# 如果被请求的是大文件
if (bereq.url ~ "^[^?]*\.(bmp|bz2|doc|eot|flv|gif|gz|ico|jpeg|jpg|less|mp[34]|pdf|png|rar|rtf|swf|tar|tgz|txt|wav|woff|xml|zip)(\?.*)?$") {
unset beresp.http.set-cookie ; # 取消设置缓存
set beresp.ttl = 1h ; # 设置生命周期为1小时
}

# 如果请求的是静态文件
if (bereq.url ~ "^[^?]*\.(css|js|html)(\?.*)?$") {
set beresp.ttl = 10m ; # 设置生命周期为10分钟
}

if (beresp.ttl <= 0s || beresp.http.Set-Cookie || beresp.http.Vary == "*") {
set beresp.ttl = 120s ;
set beresp.uncacheable = true ; # 设置不缓存
return (deliver) ;
}

set beresp.grace = 1h;

return (deliver) ;
}
sub vcl_deliver {
if (obj.hits > 0) { # 如果命中缓存次数大于0,表示varnish中有缓存,直接使用缓存
set resp.http.X-Cache = "Cache" ;
}else { # 否则就从目标服务器拉取数据
set resp.http.X-Cache = "UnCache" ;
}

return (deliver) ; # 最终返回客户端
}

测试

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
curl -I rack-leen.top:6081 # 首次获取header信息
HTTP/1.1 200 OK
Date: Thu, 31 Oct 2019 09:47:07 GMT
Server: Apache
X-Frame-Options: SAMEORIGIN
Last-Modified: Mon, 29 Jul 2019 10:16:47 GMT
Vary: Accept-Encoding
Content-Type: text/html
X-Varnish: 98307
Age: 0
Via: 1.1 varnish-v4
ETag: W/"2602a-58ecf3085c1c0-gzip"
X-Cache: UnCache # 这里表示varnish还没有缓存,直接拉取的目标服务器数据
Connection: keep-alive

curl -I rack-leen.top:6081 # 再次获取header信息
HTTP/1.1 200 OK
Date: Thu, 31 Oct 2019 09:10:48 GMT
Server: Apache
X-Frame-Options: SAMEORIGIN
Last-Modified: Mon, 29 Jul 2019 10:16:47 GMT
Vary: Accept-Encoding
Content-Type: text/html
X-Varnish: 65555 65551
Age: 2117
Via: 1.1 varnish-v4
ETag: W/"2602a-58ecf3085c1c0-gzip"
X-Cache: Cache # 之前已经将信息缓存下来,这里已经开始访问缓存
Connection: keep-alive

curl -X PURGE rack-leen.top:6081 # 清除缓存
<!DOCTYPE html>
<html>
<head>
<title>200 Purged</title>
</head>
<body>
<h1>Error 200 Purged</h1>
<p>Purged</p>
<h3>Guru Meditation:</h3>
<p>XID: 32778</p>
<hr>
<p>Varnish cache server</p>
</body>
</html>
文章作者: rack-leen
文章链接: http://yoursite.com/2019/11/28/%E5%B7%A5%E5%85%B7%E5%AE%89%E8%A3%85%E4%B8%8E%E9%83%A8%E7%BD%B2/varnish%E5%AE%89%E8%A3%85%E4%B8%8E%E5%BA%94%E7%94%A8/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 rack-leen's blog
打赏
  • 微信
  • 支付宝

评论