一、理论基础
- 二种常用的开源解决方案squid、varnish
- 条件式请求解决缓存与后端服务器内容更新不匹配问题的二种解决方案(http1.1才支持条件式请求,http1.0只支持过期机制)
● last modified /If-Modified-Since:基于时间戳来请求,客户端会发一个首部,自从这个时间之后你有没有改变过
● Etag(扩展标记)/If-None-Match:每次服务端内容改变生成Etag发给客户端,客户端每次请求将Etag发给服务端,服务端将请求内容提取出来hash出Etag 进行比较 - 判断过期与否:过期时间Expires
● HTTP/1.0
Expires:过期
● HTTP/1.1
Cache-Control:maxage= (所有缓存的缓存时长)
Cache-Control:s-maxage= (公共缓存的缓存时长) - 程序架构
● Manager进程
● Cacher进程,包含多种类型的线程accept、worker、expiry.......
● shared memory log:共享内存日志(滚动存储只有80M左右大小)
查看保存导出类小工具:varnishlog,varnishcsa,varnishstat.....
● 配置接口:VCL(varnish configuration language) - varnish的程序环境
● /etc/varnish/varnish.params:配置varnish服务进程的工作特性,例如监听的地址和端口,缓存机制;
● /etc/varnish/default.vcl:配置各child/cache线程的缓存策略
● /usr/sbin/varnishd: 主程序
● /usr/bin/varnishadm: 管理命令接口
● Shared Memory Log 交互工具
/usr/bin/varnishhist
/usr/bin/varnishlog
/usr/bin/varnishcsa
/usr/bin/varnishstat
/usr/bin/varnishtop
● 测试工具程序:/usr/bin/varnishtest
● VCL配置文件重载程序:/usr/sbin/varnish_reload_vcl - 常用状态引擎:
● 前端线程Frontend Workthread
vcl_recv ,vcl_hash, vcl_hit, vcl_miss, vcl_purge, vcl_pipe, vcl_pass
vcl_deliver, vcl_synth
● 后端线程对服务器端Backend Workthead
vcl_backend_fetch, vcl_backedn_response, vcl_backend_error - 查看状态引擎的一些默认配置
● varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082 连上管理程序
● help 一下,看到一些管控的子命令
● vcl.list :查看当前生效的配置
● vcl.show boot 查看生效配置的代码 vcl.show -v boot 查看详细的默认代码 - 内部常用变量总结(分三大类req类,be类,obj类)
● req.method :http请求方法(GET,HEAD,PUT,POST,TRACE,OPTIONS,DELETE
● req.http.Authorization:用户的请求认证方法
● req.url:请求报文中的url
● req.http.Cookie:用户的请求cookie信息
● req.http.User_Agent ~ "chrome" 用户浏览器类型
● req.http.Referer:防盗链用的,从那跳转过来
● bereq.http.HEAERS
● berep.request:请求方法
● bereq.url:请求的url
● bereq.proto:请求相关的协议
● bereq.backend:指明要调用的后端主机
● beresp.http.HEADERS
● beresp.status:响应的状态码
● beresp.proto:协议版本
● beresp.backend.name:BE主机的主机名
● beresp.ttl:BE主机响应的内容的余下的可缓存时长
● obj.hits:此对象从缓存中命中的次数
● obj.ttl:对象的ttl值
● server.ip:varnish主机的IP
● server.hostname:varnish主机的hostname
● clien.ip:发请求至varnish主机的客户端IP
● 用户自定义:set ,unset
● 示例1:强制对某类资源的请求不检查缓存
● 示例2:对于特定类型的资源,例如公开的图片等,取消其私有标识,并强行设定基可以varnish缓存的时长;定义在val_backend_response中
● 示例3:定义在val_recv中
二、缓存对象的修剪purge,ban等操作
- 能执行purge操作
sub vcl_purge {
return (synth(200,"Purged"));
} - 何时执行purge操作
sub vcl_recv{
if ( req.method == "PURGE") {
return(purge);
}
} - 对此类请求添加访问控制机制
acl purgers {
"127.0.0.0"/8;
"10.1.0.0"/16;
}
sub vcl_recv {
if (req.method == "PURGE") {
if ( !client.ip ~ purgers ) {
return(synth(405,"purging not allowed for" + client.ip));
}
return(purge);
}
} - 将同类操作ban在一起,ban的设置
● 在varnishadm命令下,用ban命令(方法1)
● ban < field><operator><arg>
示:ban req.url ~ ^/javascripts
● 在配置文件中定义,使用ban()函数(方法2)
示:if ( req.method == "BAN" ) {
ban("req.http.host ==" + req.http.host + "&&req.url ==" +req.url);
return(synth(200,"ban added"));
}
三、varnish后连多个终端,实现动静资源分离
backend default {
.host = "172.16.100.6";
.port = "80";
}
backend appsrv {
.host = "172.16.100.7";
.port = "80";
}
sub vcl_recv {
if (req.url ~ "(?i).php$") {
set req.backend_hint = appsrv;
} else {
set req.backedn_hint = default;
}
}
四、后端同种资源服务器之间的调度
使用前先导入import directors
示例:
import directors:
backend server1 {
.host=
.port=
}
backend server2 {
.host =
.port =
}
sub vcl_init { #初始化一下,把同样功能的多个服务器定义为一个组
new GROUP_NAME = directors.round_robin(); 设置调度算法
GOUP_NAME.add_backend(server1);
GOUP_NAME.add_backend(server2);
}
sub vcl_recv {
set req.backend_hint = GROUP_NAME.backend();
}基于cookie的session sticky
sub vcl_init {
new h = directors.hash();
h.add_backend(one,1); // backend 'one' with weight '1'
h.add_backend(two,1); //backend 'two' with weight '1'
}
sub vcl_recv {
set req.backend_hint = h.backend(req.http.cookie);
}后端主机健康状态检查
● 方法一:每个backend里都定义
backend BE_NAME {
.host =
.port =
.probe = {
.url= 对哪个url进行检查
.timeout= 超时时间
.interval= 每隔多长时间检查一次
.window= 基于最近的几次进行判断
.threshold= 域 值 ,有几次成功的次数
}
}
● 统一定义,后面各自调用
● 示例:
probe check {
.url = "/.healthcheck.html";
.window = 5;
.threshold = 4;
.interval = 2s;
.timeout = 1s;
}
backend default {
.host = "10.1.1.68";
.port = "80";
.porbe = check;
}
backend appsrv {
.host = "10.1.1.69";
.port = "80";
.probe = "check";
}
● 手动设置为管理healthy与sick状态,在varnishadm连接命令下
backend.set_health server1 sick 设置
backend.list 查看
backend.set_health auto 再恢复原有设置设置后端的主机属性:
backend BE_NAME {
.....
.connect_timeout = 0.5s;
.first_byte_timeout = 20s;
.between_bytes_timeout = 5s;
.max_connections = 50;
}设置修改进程池,等相关参数的设置,并永久有效
● /etc/varnish/varnish.params 修改或者添加
● DAEMON_OPTS="-p thread_pools=4 -p thread_pool_max=10000"
● 设了四个进程池,每个进程池一万并发量
● thread_pool_min :最大空闲线程数
● thread_pool_timeout:线程空闲时长,并移除掉
● thread_pool_add_delay:添加新线程的延时期
● thread_pool_destroy_delay:线程超时后,再给个宽限期
五、varnish日志工具
- varnishstat
● varnishstat -1 -f MAIN.cache_hit -f MAIN.cache_miss
显示指定参数的当前统计数据
● varnishstat -l -f MAIN -f MEMPOOL
列出指定配置段的每个参数的意义 - varnishtop
- varnishlog :以KV数据显示日志信息
● varnishncsa:以传统格式显示
● varnishncsa -D -a -w /var/log/varnish/access.log 自己手动指明日志保存到什么位置的文件中