首页 > 代码库 > varnish浅析
varnish浅析
安装varnish,安装包需要到官网下载http://www.varnish-cache.org/releases/index.html
varnish的程序环境:
/etc/varnish/varnish.params:配置varnish服务进程的工作特性,例如监听的地址、端口及缓存机制等; /etc/varnish/default.vcl:配置各Child/Cache线程的工作属性; /usr/sbin/varnishd:ansible的主程序 /usr/bin/varnishadm:命令行接口工具 共享内存日志的交互工具: /usr/bin/varnishhist /usr/bin/varnishlog /usr/bin/varnishncsa /usr/bin/varnishstat /usr/bin/varnishtop /usr/bin/varnishtest:测试工具程序 /usr/sbin/varnish_reload_vcl:vcl配置文件重载程序,在varnishadm命令中有一个内置命令vcl.load可达到同样效果 [root@localhost ~]# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082 systemd unit file: /usr/lib/systemd/system/varnish.service:varnish服务 /usr/lib/systemd/system/varnishlog.service:日志持久的服务 /usr/lib/systemd/system/varnishncsa.service:日志持久的服务
varnish的缓存存储机制:
malloc [,size]:内存存储,size用于定义空间大小;重启后所有缓存项失效; file [,path[,size[,granularity]]]:文件格式存储,是一个黑盒文件(对用户不可见,其组织格式,用户是无法参与的),重启后所有缓存项失效; persistent [path,size]:文件格式存储,黑盒文件,重启后所有缓存项有效,但目前在实验阶段;
varnish程序的选项:
/etc/varnish/varnish.params文件的变量和/usr/lib/systemd/system/varnish.service文件是相联系的 程序选项:/etc/varnish/varnish.params文件 -a address[:port][,address[:port][...],默认为6081端口; -T address[:port],默认为6082端口; -s [name=]type[,options],定义缓存存储机制; -u user -g group -f config:VCL配置文件; -F:运行于前台; ... 运行时参数:/etc/varnish/varnish.params文件, DEAMON_OPTS DAEMON_OPTS="-p thread_pool_min=5 -p thread_pool_max=500 -p thread_pool_timeout=300" -p param=value:设定运行参数及其值; 可重复使用多次; -r param[,param...]: 设定指定的参数为只读状态;
varnishadm -S /etc/varnish/secret -T [ADDRESS:]PORT 有以下内置命令
help [<command>] ping [<timestamp>] auth <response> quit banner status:显示当前varnish服务状态 start:启动进程 stop:停止进程 vcl.load <configname> <filename>:手动加载一个配置文件版本(原文件修改了) vcl.inline <configname> <quoted_VCLstring> vcl.use <configname>:指定要使用的配置列表中的某个配置文件(版本) vcl.discard <configname>:删除某个版本的配置文件 vcl.list:列出编译成功的配置列表 param.show [-l] [<param>]:列出可使用的配置参数 param.set <param> <value>:修改某个配置参数 eg:param.set thread_pool_max 1024 panic.show panic.clear storage.list vcl.show [-v] <configname> backend.list [<backend_expression>]:列出后端服务器列表 backend.set_health <backend_expression> <state>:定义后端主机的健康状态的检查机制 ban <field> <operator> <arg> [&& <field> <oper> <arg>]... ban.list 配置文件相关: vcl.list vcl.load:装载,加载并编译; vcl.use:激活; vcl.discard:删除; vcl.show [-v] <configname>:查看指定的配置文件的详细信息; 运行时参数: param.show -l:显示列表; param.show <PARAM> param.set <PARAM> <VALUE> 缓存存储: storage.list 后端服务器: backend.list
VCL:
varnish的规则配置语言,是“域”专有类型的配置语言 VCL有多个状态引擎,状态之间存在相关性,但彼此间互相隔离;每个状态引擎可使用return(x)指明关联至哪个下一级引擎;如:vcl_hash --> return(hit) --> vcl_hit
vcl流程图
状态引擎切换机制:
request报文由vcl_recv接收,response报文由vcl_deliber发送,几种常用切换如下: (1)vcl_recv --> vcl_hash --> vcl_hit --> vcl_deliver (2)vcl_recv --> vcl_hash --> vcl_miss --> vcl_backend_fetch --> vcl_backend_response(vcl_backend_error) --> vcl_dliver (3)vcl_recv --> vcl_hash --> vcl_purge --> vcl_synth (4)vcl_recv --> vcl_hash --> vcl_pipe 两个特殊的引擎: vcl_init:在处理任何请求之前要执行的vcl代码:主要用于初始化VMODs; vcl_fini:所有的请求都已经结束,在vcl配置被丢弃时调用;主要用于清理VMODs;
vcl的语法格式:
(1) VCL files start with vcl 4.0; 以下语法适合4.0,需放在default.vcl文件第一行 (2) //, # and /* foo */ for comments; 用于注释 (3) Subroutines(子程序) are declared with the sub keyword;子例程使用sub关键字进行声明,例如sub vcl_recv { ... } (4) No loops, state-limited variables;不支持循环,支持限于引擎的内建的状态变量(req* , bereq* , obj* , ...) (5) Terminating statements with a keyword for next action as argument of the return() function, i.e.: return(action); (6) Domain-specific; 域专用状态
The VCL Finite(有限的) State Machine(vcl的有限状态机)
(1) Each request is processed separately; 每个请求都被单独处理 (2) Each request is independent from others at any given time; 每个请求在任何时间与其他请求之间都是隔离的 (3) States are related(关联的), but isolated(分离的); (4) return(action); exits one state and instructs(命令) Varnish to proceed to the next state; 状态切换是靠return完成的 (5) Built-in VCL code is always present and appended(附加) below your own VCL; 内建vcl代码一直有效并附加在你自定义的vcl之后(在varnishadm中使用vcl.show查看)
VCL Built-in Functions and Keywords(vcl的内建函数和keyword)
函数: regsub(str, regex, sub):基于"str"字符串,被regex匹配到的字符串替换为"sub" regsuball(str, regex, sub):全局替换 ban(boolean expression) hash_data(input) synthetic(str) Keywords: call subroutine return(action) new set unset 操作符: ==, !=, ~, >, >=, <, <= 逻辑操作符:&&, ||, ! 变量赋值:= 示例:如下图
varnish变量类型:
内建变量: req.*:request,表示由客户端发来的请求报文相关; req.http.* req.http.User-Agent, req.http.Referer, ... bereq.*:由varnish主机发往后端主机的httpd请求相关; bereq.http.* beresp.*:由后端主机响应给varnish主机的响应报文相关; beresp.http.* resp.*:由varnish响应给client相关; obj.*:存储在缓存空间中的缓存对象的属性;只读; 常用变量: bereq.*, req.*: bereq.http.HEADERS:http请求报文的某个首部 bereq.request:请求方法; bereq.url:请求的url; bereq.proto:请求的协议版本; bereq.backend:指明要调用的后端主机; req.http.Cookie:客户端的请求报文中Cookie首部的值; req.http.User-Agent ~ "chrome" beresp.*, resp.*: beresp.http.HEADERS beresp.status:响应的状态码; reresp.proto:协议版本; beresp.backend.name:BE主机的主机名; beresp.ttl:BE主机响应的内容的余下的可缓存时长; obj.* obj.hits:此对象从缓存中命中的次数; obj.ttl:对象的ttl值 server.* server.ip server.hostname client.* client.ip 用户自定义: set unset
示例1:强制对某类资源的请求不检查缓存:
sub vcl_recv { if (req.url ~ "(?i)^/(login|admin)"){ return(pass); (login或admin开头的URL直接miss,不查询缓存) } } 此列不能再浏览器中测试,因为浏览器会在miss后varnish后直接请求后端主机,用下面命令查看 [root@keepalived2 ~]# curl -I http://10.1.51.10/login/index.html
示例2:对于特定类型的资源,例如公开的图片等,取消其私有标识,并强行设定其可以由varnish缓存的时长;
sub vcl_backend_response { if (beresp.http.cache-control !~ "s-maxage") { if (bereq.url ~ "(?i)\.(jpg|jpeg|png|gif|css|js)$") { unset beresp.http.Set-Cookie; set beresp.ttl = 3600s; } } }
缓存对象的修剪(仅授权管理员):purge(清理单个缓存), ban (清理能被模式匹配到的所有缓存)
示例1:
sub vcl_recv { if (req.method == "PURGE") { return (purge); (定义请求方法为PURGE) } } sub vcl_purge { return(synth(200,"purged")); (当purge请求时,返回自定义状态) } 需要使用curl命令测试,先用-X选项指定用PURGE方法请求,此时会清理对应请求的缓存,再用-I选项时可看到结果为miss。
示例2:限制指定用户可使用purge;
acl purgers { "127.0.0.0"/8; "10.1.0.0"/16; } (定义预习使用purge的用户) sub vcl_recv { if (req.method == "PURGE") { if (!client.ip ~ purgers) { return(synth(405,"Purging not allowed for " + client.ip)); } return(purge); } } 如果非指定用户(ip)访问,会返回405状态码(curl命令测试)
director轮询
(1)不同请求响应不同内容
backend default { .host = "10.1.51.20"; .port = "80"; } backend appsrv { .host = "10.1.51.30"; .port = "80"; } sub vcl_recv { if (req.url ~ "(?i)\.php$") {(后缀为php的则访问主机appsrv,其他访问default) set req.backend_hint = appsrv; }else { set req.backend_hint = default; } }
(2)轮询,负载均衡效果
import directors; backend default { .host = "10.1.51.20"; .port = "80"; } backend appsrv { .host = "10.1.51.30"; .port = "80"; } sub vcl_init { new websrvs = directors.round_robin(); websrvs.add_backend(default); websrvs.add_backend(appsrv); } sub vcl_recv { set req.backend_hint = websrvs; } 使用curl命令进行测试可以更好的看到效果,浏览器会在命中后,在缓存有效期内都只会返回第二次命中的后端主机的记录。
后端主机的健康检测:
.probe:定义健康状态检测方法; .url:检测时请求的URL,默认为”/"; .request:发出的具体请求; .request = "GET /.healthtest.html HTTP/1.1" "Host: www.magedu.com" "Connection: close" .window:基于最近的多少次检查来判断其健康状态; .threshold:最近.window中定义的这么多次检查中至有.threshhold定义的次数是成功的;如.window=5 .threshhold=3,那5次检测中至少3次成功的才为成功 .interval:检测频度; .timeout:超时时长; .expected_response:期望的响应码,默认为200;
示例:
probe check { .url = "/.healthcheck.html"; (在根目录中定义一个测试网页) .window = 5; .threshold = 4; .interval = 2s; .timeout = 1s; } backend default { .host = "10.1.51.20"; .port = "80"; .probe = check; } backend appsrv { .host = "10.1.51.30"; .port = "80"; .probe = check; } 注意probe放置的位置,在最前面是,如果测试失败则该主机后面的网页不能访问 在varnishadm中使用内置命令backend.list可以查看命中(测试)的结果,可使用backend.set_health命令手动设置后端主机的健康状态(sick,healthy 永久哦)
varnish的运行参数:param.show -l查看所有参数
线程相关的参数: 在线程池内部,其每一个请求由一个线程来处理; 其worker线程的最大数决定了varnish的并发响应能力; thread_pools:Number of worker thread pools. 最好小于或等于CPU核心数量; thread_pool_max:The maximum number of worker threads in each pool.每个线程池的最大线程数 thread_pool_min:The minimum number of worker threads in each pool. 额外意义为“最大空闲线程数”; 最大并发连接数=thread_pools * thread_pool_max thread_pool_timeout:Thread idle threshold. Threads in excess of thread_pool_min, which have been idle for at least this long, will be destroyed.每个线程空闲超时时长,超时就杀掉,但是不能低于最小线程数; thread_pool_add_delay:Wait at least this long after creating a thread. thread_pool_destroy_delay:Wait this long after destroying a thread. 设置方式:在varnishadm中 vcl.param 永久有效的方法: varnish.params文件最后一行 DEAMON_OPTS="-p PARAM1=VALUE -p PARAM2=VALUE"
varnish日志区域:
1、varnishstat - Varnish Cache statistics -1 :将某时刻的状态全部列出 -1 -f FILED_NAME -l:可用于-f选项指定的字段名称列表; 示例: # varnishstat -1 -f MAIN.cache_hit -f MAIN.cache_miss 2、varnishtop - Varnish log entry ranking -1 Instead of a continously updated display, print the statistics once and exit. -i taglist,可以同时使用多个-i选项,也可以一个选项跟上多个标签; -I <[taglist:]regex> -x taglist:排除列表 -X <[taglist:]regex> 示例: # varnishtop -I ReqURL:/ -I ReqURL:/ 3、varnishlog - Display Varnish logs 4、 varnishncsa - Display Varnish logs in Apache / NCSA combined log format
本文出自 “新手学Linux” 博客,请务必保留此出处http://kop309.blog.51cto.com/9034739/1872359
varnish浅析
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。