http cache的实现方式有两种: Squid、Varnish;一般被称为缓存服务器
Squid:支持正向和反向代理、是一款重量级的缓存服务器,在高负载的情况下,性能非常的稳定
Varnish:支持反向代理;相比于Squid是非常轻量级的缓存服务器,在高负载情况下,性能较差,没有Squid稳定;一般被称为http加速器;
Varnish的特点:
一、组成部分
Management:作为主控进程;提供命令行接口、管理各种子进程、初始化,加载文件等等
Child/Cache:缓存管理、日志数据统计、接受用户请求、对所有缓存做有效性在验证,清理
VCL:Varnish的配置语言;缓存控制机制,调用C编译器,生成二进制程序,让子进程加载
二、工作模式:
1、请求的资源可缓存:
(1)当客户端请求的资源命中了Varnish缓存且缓存未过期时,将直接响应给客户端;
(2)Varnish作为一台反向代理缓存服务器,当客户端请求的资源未命中Varnish缓存时,Varnish会扮演客户端角色去后端主机请求数据,将请求到的资源先缓存到本地,随后再将请求到的资源发送给客户端。
(3)当客户端请求的资源命中了Varnish缓存,但是Varnish上的缓存已过期时,则Varnish会去后端主机确认请求原始资源是否更新;如果未更新,则后端主机仅响应资源首部给Varnish,随后Varnish再将响应资源发送给客户端;如果请求原始资源更新,则后端主机将会响应新的资源给Varnish,Varnish将响应的资源缓存在本地之后再响应给客户端;如果请求的资源后端主机已删除,则Varnish中的缓存也会被删除,响应给客户端404页面
2、请求的资源不可缓存:
(1)当客户端请求的资源为不可缓存时,Varnish会直接去后端主机取得相应内容直接返回给客户端;而不是先缓存到本地再响应给客户端
衡量一个缓存的有效性:
缓存的命中率:
文档命中率:也称为资源命中率,从文档的个数进行衡量
字节命中率:从内容的大小进行衡量
缓存的生命周期:
缓存项过期:惰性清理
缓存空间用尽:使用LRU算法(最近最少使用算法)
注意:当一个缓存项过期时并不会真正从内存中青旅,只是标记为失效,而不是把它删除;当内存空间用尽时,才会真正的删除缓存项
三、缓存模式:
(1)file:缓存再磁盘的文件中,自行管理的关键系统
(2)malloc:内存缓存;使用malloc()库调用,在varnish启动时向内存申请指定大小的空间进行缓存
(3)presistent:存储在磁盘上;
四、缓存新鲜度检测机制
有效性在验证:
如果原始内容发生改变,则仅响应首部(不用到body部分;响应码为304(Not Modified)
如果原始内容发生了改变,则正常响应给客户端,响应码为200
如果原始内容消失,则响应404,此时缓存中的缓存项(object)也应该被删除
条件式请求首部:
If-Modified_Since:基于原始内容的最近一个修改的时间戳进行验证
If-Ummodified_since:如果缓存发生了改变,响应304
If-Match:基于请求内容的匹配做验证
If-None_match:基于Etag比较进行内容验证
五、缓存控制机制
过期日期:
HTTP/1.0 Expires:给与的是绝对时长
例如:Expires:Thu, 04 Jun 2015 23:38:18 GMT
HTTP/1.1 Cache-Control: max-age:给与的是相对时长,从接受到相应报文开始
例如:Cache-Control:max-age=700
六、VCL相关的状态引擎
vcl_recv:接受请求
vcl_hash:
hit:vcl_hit:命中缓存
miss:vcl_miss:未命中缓存
purge:vcl_purge:清除缓存
pipe:vcl_pipe:管道;直接发送给后端主机
pass、hit_for_pass:vcl_pass ##跳过,直接请求后端主机
vcl_backend_fetch:读取数据
vcl_backend_response:后端主机响应
vcl_backend_error:后端主机响应错误码
vcl_synth:同步
vcl_deliver:响应给客户端
七、VCL的语法格式
(1)表示注释://、#、/*……*/
(2)定义子例程
(3)不支持循环、支持条件判断
(4)具有内建变量
(5)使用终止语句return,没有返回值
(6)支持操作符:=、==、!=、&&、||
八、VCl内建变量
req.*:只匹配客户端发来的请求
req.http.*:匹配http请求报文的任何首部
bereq.*:由varnish向后端主机发出http请求
beresp.*:由后端主机发来http的响应报文首部
resp.*:由varnish响应给客户端的http的响应报文
obj.*:存储在缓存空间中的缓存的对应属性
常用的变量:
berep:varnish向后端主机请求资源
bereq.request:请求方法(向后端主机发送请求报文)
bereq.url:请求的url
bereq.proto:请求协议
bereq.backend:指明要调用的后端主机是那个
beresp:后端主机向varnish响应资源
beresp.proto:响应协议
beresp.status:响应的状态码
beresp.reason:响应原因
beresp.backend.name:后端主机名称
beresp.ttl:后端主机请求中的内容的余下的生存时长
obj.hits:此对象从缓存中命中的次数
obj.ttl:对象的ttl值;也被称为缓存时长
准备环境:CentOS 7
Varnish服务器 | IP:172.18.42.200 |
后端主机1:提供httpd服务 | IP:172.18.42.201 |
后端主机2:提供httpd服务 | IP:172.18.42.202 |
一、Varnish服务器配置
1、安装varnish
[root@node0 ~]# yum install varnish [root@node0 ~]# ll /etc/varnish/ total 20 -rw-r--r-- 1 root root 1155 May 20 17:07 default.vcl ##配置Varnish缓存策略 -rw-r--r-- 1 root root 1224 May 20 11:10 default.vcl.wtc -rw------- 1 root root 37 May 20 11:09 secret -rw-r--r-- 1 root root 1200 Mar 16 2015 varnish.params ##配置缓存机制 -rw-r--r-- 1 root root 1200 May 20 11:12 varnish.params.bak
2、更改varnish的缓存模式:
[root@node0 varnish]# vim varnish.params #VARNISH_STORAGE="file,/var/lib/varnish/varnish_storage.bin,1G" ##默认的缓存机制 VARNISH_STORAGE="malloc,1G" ##更改缓存为malloc模式
3、定义后端主机
[root@node0 varnish]# vim default.vcl ## backend default { .host = "172.18.42.202"; ##后端主机1 .port = "80"; ##web80端口 }
二、配置后端主机
1、后端主机1安装httpd、php
[root@node1 ~]# yum install httpd -y [root@node1 html]# systemctl start httpd.service
2、后端主机2安装httpd
[root@node2 ~]# yum install nginx [root@node2 nginx]# nginx
三、配置default.vcl缓存策略
1、当请求资源可缓存时,查看缓存是否命中
sub vcl_deliver { if (obj.hits>0) { set resp.http.X-Cache = "HIT"; } else { set resp.http.X-Cache = "MISS"; } } ##如果请求的资源未命中则显示MISS、命中则显示HIT
第一次请求:
第二次请求:命中了varnish缓存
2、强制对某些资源不检查缓存
[root@node2 ~]# mkdir /web/lweim/wtc ##在后端主机新目录“wtc” [root@node2 ~]# vim /web/lweim/wtc/index.html sub vcl_recv { if (req.url ~ "(?i)^/wtc") { return(pass); } } ##当请求的url当中有“wtc”时,则不会去命中缓存,而是直接由varnish请求后端主机
第一次请求:
第二次请求:
3、定义多台后端主机
backend web2 { .host = "172.18.42.202"; .port = "80"; } backend web1 { .host = "172.18.42.201"; .port = "80"; } sub vcl_recv { if (req.url ~ "(?i)\.php$") { set req.backend_hint = web1; ##当请求url中有php时,则是后端主机web1来响应 return(pass); } else { set req.backend_hint = web2; ##url中没有php的请求都由后端主机web2来响应 return(pass); } }
第一次请求静态资源
第二次请求php
4、实现负载均衡
import directors; ##定义一个主机组 backend web1 { ##定义第一个后端服务器 .host = "172.18.42.201"; .port = "80"; } backend web2 { ##定义第二个后端服务器 .host = "172.18.42.202"; .port = "80"; } sub vcl_init { ##定义一个服务器组 new web = directors.round_robin(); web.add_backend(web1); web.add_backend(web2); } sub vcl_recv { if (req.url ~ "(?i)^/wtc") { set req.backend_hint = web.backend(); return(pass); ##直接请求后端主机服务器 } }
第一次请求:
第二次请求:
5、对后端主机做健康检测
backend web1 { .host = "172.18.42.201"; .port = "80"; .probe = { .url = "/"; .interval = 1s; ##每隔多长时间检测一次 .window = 8; ##指定后端主机要检测多少次 .threshold 5; ##指定至少要有几次是检测成功的 .timeout 2s; ##指定检测时间的超时时长;默认为2s }
6、修改varnish运行时命令参数
[root@node0 varnish]# varnishstat MAIN.pools 4 0.00 . 4.00 [root@node0 ~]# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082 param.set thread_pools 2 200 ##响应码为200即为修改成功 [root@node0 varnish]# varnishstat MAIN.pools 2 0.00 . 2.00
7、查看varnish的工作状态及其相关信息
[root@node0 varnish]# varnishstat