Varnish简介
- Varnish是一款高性能的开源HTTP加速器。(是一款高性能的开源反向代理服务器和缓存服务器)
varnish的特点
- (1)是基于内存缓存,重启后数据将消失。 (2)利用虚拟内存方式,io性能好。 (3)支持设置0~60秒内的精确缓存时间。 (4)VCL配置管理比较灵活。 (5)32位机器上缓存文件大小为最大2G。 (6)具有强大的管理功能,例如top,stat,admin,list等。 (7)状态机设计巧妙,结构清晰。 (8)利用二叉堆管理缓存文件,达到积极删除目的。
varnish与squid的对比
- 说到Varnish,不能不提Squid,Squid是一个高性能的代理缓存服务器,它和varnish之间有诸多的异同点,这里分析如下:
- 下面是他们之间的相同点: (1)都是一个反向代理服务器。 (2)都是开源软件。
- 下面是它们的不同点,也是Varnish的优点: (1)Varnish的稳定性很高,两者在完成相同负荷的工作时,Squid服务器发生故障的几率要高Varnish,因为使用Squid要经常重启。 (2)Varnish访问速度更快,Varnish采了"Visual Page Cache"技术,所有缓存数据都直接从内存读取,而squid是从硬盘读取,因而Varnish在访问速度方面会更快。 (3)Varnish可以支持更多的并发连接,因为Varnish的TCP连接释放要比Squid快。因而在高并发连接情况下可以支持更多TCP连接。 (4)Varnish可以通过管理端口,使用正则表达式批量的清除部分缓存,而Squid是做不到的。 (5) squid属于是单进程使用单核CPU,但Varnish是通过fork形式打开多进程来做处理,所以是合理的使用所有核来处理相应的请求。
- 当然,与传统的Squid相比,Varnish也是有缺点的,列举如下: 1) varnish进程一旦Hang、Crash或者重启,缓存数据都会从内存中完全释放,此时所有请求都会发送到后端服务器,在高并发情况下,会给后端服务器造成很大压力。 2) 在varnish使用中如果单个url的请求通过HA/F5(负载均衡)每次请求不同的varnish服务器中,被请求varnish服务器都会被穿透到后端,而且同样的请求会在多台服务器上缓存,也会造成varnish的缓存的资源浪费,也会造成性能下降。
- 解决方案: 1) 综上所述在访问量很大的情况下推荐使用varnish的内存缓存方式启动,而且后面需要跟多台squid服务器。主要为了防止前面的varnish服务、服务器被重启的情况下,前期肯定会有很多的穿透这样squid可以担当第二层CACHE,而且也弥补了varnish缓存在内存中重启都会释放的问题。 2) 这样的问题可以在负载均衡上做url哈希,让单个url请求固定请求到一台varnish服务器上,可以解决该问题。
- 注:上面的解决方法还需要全面的测试,没有经过证实。
VCL简介
- Varnish Configuration Language(VCL)是varnish配置缓存策略的工具,它是一种基于‘域’的简单编程语言,使用VCL编写的缓存策略通常保存在.vcl文件中,其需要编以成二进制的格式后才能由varnish调用。
VCL处理流程图
处理大致分为以下几个步骤:
- Receive 状态:也就是请求处理的入口状态,根据 VCL 规则判断该请求应该是 Pass 或Pipe,或者进入 Lookup(本地查询)。
- Lookup状态:进入此状态后会在hash表中查找数据,若找到则进入Hit状态,若没找到则进入miss状态。
- Pass状态:在此状态下会进入后端请求,即进入Fetch状态。
- Fetch状态:在Fetch状态下对请求进行后端的获取,发送请求,获得数据,并进行本地的存储。
- Deliver状态:将获得的数据发送给客户端然后结束本次请求。
varnish的基本配置
实验环境
rhel7.5版本的虚拟机
selinux和firewalld都为disabled
实验主机
172.25.24.1 | varnish缓存主机 |
---|---|
172.25.254.2 | apache1服务器主机 |
172.25.254.3 | apache2服务器主机 |
varnish主机的配置
-
准备varnish的安装包,也可以在官网下载。
安装以下三个安装包。
-
我们可以通过命令查看我们安装的varnish的版本以及他的配置文件。
[root@varnish ~]# rpm -qa | grep varnish #4.0的版本
varnish-libs-4.0.5-1.el7.x86_64
varnish-4.0.5-1.el7.x86_64
[root@varnish ~]# rpm -qc varnish #相关的配置文件
/etc/logrotate.d/varnish #日志文件
/etc/varnish/default.vcl #配置文件
/etc/varnish/varnish.params #环境文件
- 安装完成后,系统生成了varnish用户。
[root@varnish ~]# id varnish
uid=998(varnish) gid=996(varnish) groups=996(varnish)
vim /etc/varnish/varnish.params
通过查看环境文件我们可以看到varnish的监听端口等信息
vim /usr/lib/systemd/system/varnish.service
可以看到最大打开的文件数以及内存锁定。
- 查看我们varnish虚拟机的内存上限,以及最大打开的文件数情况。
ulimit -l #内存上限
free -m #查看系统内存的大小
ulimit -n
sysctl -a | grep file #查看系统允许开启文件的最大个数
- 修改配置文件中监听的端口为80,并开启服务。
(目的是用户在访问的时候ip地址后面不用加入端口)
[root@varnish ~]# vim /etc/varnish/varnish.params
[root@varnish ~]# systemctl start varnish
-
注意:如果系统文件数不满足varnish用户的文件数需求的话,可以在虚拟机的管理界面添加内存来扩充系统的文件数,操作如下:
poweroff 先关掉varnish虚拟机
在虚拟机的管理界面
-
修改varnish用户和用户组的文件上限以及内存锁定。重启服务,并查看监听端口。
vim /etc/security/limits.conf #文件最后加入
varnish - nofile 131072
varnish - memlock 82000
#用户 #默认类型 #值的大小(/usr/lib/systemd/system/varnish.service中的值)
[root@varnish ~]# systemctl restart varnish
[root@varnish ~]# netstat -tnlp
- 通过查看root和varnish两个用户的进程状态可以查看varnish的线程。
ps aux #查看两个用户:root 和 varnish 的pid
cat /proc/1819/status #root
cat /proc/1821/status #varnish
- 在varnish主机的配置文件中添加一个后端服务器
varnish主机是一个代理服务器,apache1是web服务器。
16行
vim /etc/varnish/default.vcl #配置文件中修改
16 backend default {
17 .host = "172.25.24.2"; #apache1的ip
18 .port = "80"; #端口
19 }
systemctl restart varnish #重启服务
[root@varnish ~]# netstat -antlupe | grep varnish #查看varnish端口
tcp 0 0 127.0.0.1:6082 0.0.0.0:* LISTEN 0 26308 3268/varnishd
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 0 26319 3269/varnishd
tcp6 0 0 :::80 :::* LISTEN 0 26320 3269/varnishd
apache1主机的配置
- 安装httpd服务,编写默认发布文件,开启http服务。
yum install httpd -y
[root@apache1 ~]# cd /var/www/html/
[root@apache1 html]# vim index.html
[root@apache1 html]# cat index.html
apache1--------example.com
[root@apache1 html]# systemctl start httpd.service
[root@apache1 html]# curl localhost
测试
- 在真机上:发现访问到的是apache1主机发布文件下写的内容
curl 172.25.24.1
查看缓存命中情况以及缓存清理
查看缓存命中情况:
varnish主机:
evince + pdf文档 #在真机中,通过这个命令可以预览pdf文档
vim /etc/varnish/default.vcl #配置文件的sub vcl_deliver区域添加
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT from westos cache"; #命中成功返回这句,第一次以后都返回这句
}
else {
set resp.http.X-Cache = "MISS from westos cache"; #未命中返回这句,第一次都返回这句
}
return (deliver);
systemctl restart varnish
测试
- 在真机中:
curl -I 172.25.24.1
curl -I 172.25.24.1/index.html #varnish主机的ip
[root@foundation24 ~]# curl 172.25.24.1
apache1--------example.com
[root@foundation24 ~]# curl 172.25.24.1/index.html #两者执行结果相同,因为只有一个默认发布文件
apache1--------example.com
缓存清理
varnish主机:
- 手动清除缓存命令:
[root@varnish ~]# varnishadm ban req.url "~" / #清除所有缓存
[root@varnish ~]# varnishadm ban req.url "~" /index.html #只清除index.html文件的缓存
man vcl
可以看到参数的具体的含义和用处
Operators
The following operators are available in VCL:
= Assignment operator.
== Comparison.
~ Match. Can either be used with regular expressions or ACLs.
! Negation.
&& Logical and.
|| Logical or.
测试:
- 在真机中:
curl -I 172.25.24.1
curl -I 172.25.24.1/index.html
定义多后端
apache2主机:
[root@apache2 ~]# yum install httpd -y
[root@apache2 ~]# cd /var/www/html/
[root@apache2 html]# vim index.html
[root@apache2 html]# cat index.html
apache2--------example.com
[root@apache2 html]# systemctl start httpd.service
[root@apache2 html]# curl localhost
apache2--------example.com
varnish主机:
- 定义多个不同域名站点的后端服务器
vim /etc/varnish/default.vcl #配置文件中修改
backend web1 {
.host = "172.25.24.2"; #apache1主机
.port = "80";
}
backend web2 {
.host = "172.25.24.3"; #apache2主机
.port = "80";
}
当访问 www.apache1.com域名时从 web1 上取数据,
访问www.apache2.com域名时到 web2 取数据,
访问其他页面报错。
在sub vcl_recv区域加入:
if (req.http.host ~ "^(www.)?apache1.com") {
set req.http.host = "www.apache1.com";
set req.backend_hint = web1;
} elsif (req.http.host ~ "^www.apache2.com") {
set req.backend_hint = web2;
} else {
return (synth(405));
}
systemctl restart varnish #重启服务
测试:
- 在真机的解析文件
/etc/hosts
中做以下解析:
172.25.24.1 www.apache1.com www.apache2.com
[root@foundation24 ~]# curl www.apache1.com
apache1--------example.com #apache1主机
[root@foundation24 ~]# curl www.apache2.com
apache2--------example.com #apache2主机
varnish主机:
man vmod_directors #查看调度器的帮助文档
[root@varnish vmods]# vim /etc/varnish/default.vcl #配置文件中修改:
14 import directors from "/usr/lib64/varnish/vmods/libvmod_directors.so"; #导入调度器的配置文件
16 backend web1 {
17 .host = "172.25.24.2";
18 .port = "80";
19 }
20 backend web2 {
21 .host = "172.25.24.3";
22 .port = "80";
23 }
24 sub vcl_init {
25 new lb = directors.round_robin(); #轮询,web1和web2
26 lb.add_backend(web1);
27 lb.add_backend(web2);
28 }
30 sub vcl_recv {
35 if (req.http.host ~ "^(www.)?apache1.com") { #apache1为轮询
36 set req.http.host = "www.apache1.com";
37 set req.backend_hint = lb.backend();
38 return (pass); #为了后面看到实验效果 不缓存
39 } elsif (req.http.host ~ "^www.apache2.com") { #apache2不变
40 set req.backend_hint = web2;
41 } else { #访问其他的报错
42 return (synth(405));
43 }
44 }
[root@varnish vmods]# systemctl restart varnish #重启服务
测试:
- 在真机中:
curl www.apache1.com
curl www.apache2.com
varnish——cdn推送平台
- bansys 有两种工作模式,分别是:telnet 和 http 模式。
- telnet 模式需要关闭 varnish 服务管理端口的验证,注释掉/etc/sysconfig/varnish 文件中的 “ -S $ {VARNISH_SECRET_FILE}”这行,重启 varnish 服务即可。
- 如果是 http模式需要对 varnish 做以下设置:
apache2主机:
- 建立虚拟主机:
[root@apache2 html]# cd /etc/httpd/conf.d/
[root@apache2 conf.d]# vim vhost.conf
<VirtualHost *:80>
DocumentRoot /www
ServerName www.apache1.com
</virtualHost>
<Directory "/www">
Require all granted
</Directory>
<VirtualHost *:80>
DocumentRoot /bbs
ServerName www.apache2.com
</virtualHost>
<Directory "/bbs">
Require all granted
</Directory>
[root@apache2 conf.d]# mkdir /www /bbs #新建虚拟主机配置文件中写的目录
[root@apache2 conf.d]# vim /www/index.html #以及默认发布文件
[root@apache2 conf.d]# vim /bbs/index.html
[root@apache2 conf.d]# cat /www/index.html
www.westos.org
[root@apache2 conf.d]# cat /bbs/index.html
bbs.westos.org
systemctl restart httpd #重启httpd
测试:
- 在真机中:
varnish主机:
- 下载cdn推送平台的压缩包,以及下面几个服务
前端界面需要安装 php 支持,下载解压的工具,php,以及apache
yum install httpd php unzip.x86_64 -y
- 解压压缩包,并修改其中的配置。
[root@varnish ~]# unzip bansys.zip -d /var/www/html/ #解压到指定目录
[root@varnish ~]# cd /var/www/html/
[root@varnish html]# ls
bansys
[root@varnish html]# cd bansys/
[root@varnish bansys]# ls
class_socket.php config.php index.php purge_action.php static #修改config文件,只保留部分设置
[root@varnish bansys]# vim config.php
[root@varnish bansys]# mv * ../ #将目录中的内容都移动到此目录的上一级目录
[root@varnish bansys]# cd ..
[root@varnish html]# ls
bansys class_socket.php config.php index.php purge_action.php static
- config.php文件的内容修改为以下:
- 因为varnish的端口我们之前改为80了,防止冲突我们更改http的端口为8080。
[root@varnish html]# cd
[root@varnish ~]# vim /etc/httpd/conf/httpd.conf
[root@varnish ~]# systemctl restart httpd.service
[root@varnish ~]# netstat -antlupe | grep httpd
tcp6 0 0 :::8080 :::* LISTEN 0 80774 23740/httpd
- 在浏览器中访问
172.25.24.1:8080
可以看到CDN推送平台的界面。
- 通过
man vcl
查看帮助文档,修改varnish的配置文件:
[root@varnish html]# vim /etc/varnish/default.vcl #中添加
16 acl westos{ #设置访问控制
17 "127.0.0.1"; #本机
18 "172.25.24.0"/24; #此网段的
19 }
sub vcl_recv #区域加入:
39 if (req.http.host ~ "^(www.)?apache1.com") {
40 set req.http.host = "www.apache1.com";
41 set req.backend_hint = lb.backend();
42 #return (pass); #之前加入的不缓存清除掉
43 } elsif (req.http.host ~ "^www.apache2.com") {
44 set req.backend_hint = web2;
45 } else {
46 return (synth(405));
47 }
49 if (req.method == "BAN") {
50 if (!client.ip ~ westos) {
51 return (synth(405,"Not allowed.")); #不在设置的网段之内的不允许清理
52 }
53 ban("req.url ~ " + req.url);
54 return(purge); #清除缓存
55 }
56 }
[root@varnish html]# systemctl restart varnis
测试:
- 在真机中:
- CDN页面清理缓存
.* | 清除所有缓存 |
---|---|
/index.html | 清除指定文件缓存 |
- 在真机中再次查看发现为MISS状态,之前的缓存被清空