一、Varnish的安装与配置
1、Varnish安装(rpm包软件)
rpm --nosignature -i https://repo.varnish-cache.org/redhat/varnish-3.0.el5.rpm yum install varnish varnish-libs-devel -y
如有安装疑惑请访问varnish官网https://www.varnish-cache.org/installation/redha
2、Varnish目录结构
/etc/sysconfig/varnish #存放Varnish运行参数设置 /etc/varnish/ #存放Varnish VCL配置文件
3、Varnish配置基本实例
3.1、修改 /etc/sysconfig/varnish
vim /etc/sysconfig/varnish #VARNISH_VCL_CONF=/etc/varnish/default.vcl VARNISH_VCL_CONF=/etc/varnish/test.vcl #调用test.vcl文件 VARNISH_LISTEN_PORT=80 #改为80端口 VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1 #监听地址 VARNISH_ADMIN_LISTEN_PORT=6082 #管理端口 VARNISH_SECRET_FILE=/etc/varnish/secret #密钥文件
3.2、提供/etc/varnish/test.vcl
cd /etc/varnish/ cp default.vcl test.vcl #复制默认配置文件
3.3、配置/etc/varnish/test.vcl
############定义健康状态检测############### probe healthcheck { .url = "/"; #定义健康检查的页面 .interval = 6s; #探测请求的发送周期,默认为5秒; .timeout = 0.3 s; #每次探测请求的过期时长 .window = 8; #设定在判定后端主机健康状态时基于最近多少次的探测进行 .threshold = 3; #在.window中指定的次数中,至少有多少次是成功的才判定后端主机正健康运行 .initial = 3; #Varnish启动时对后端主机至少需要多少次的成功探测,默认同.threshold; } ############定义两组服务器############## backend web1 { .host = "172.16.10.7"; #服务器主机 .port = "80"; #服务器端口 .probe = healthcheck; #健康状态检测 } backend web2 { .host = "172.16.10.3"; .port = "80"; .probe = healthcheck; } backend app1 { .host = "172.16.10.7"; .port = "8080"; .probe = healthcheck; } backend app2 { .host = "172.16.10.3"; .port = "8080"; .probe = healthcheck; } ############定义集群,调用服务器############## director webserver random { #定义一个名为webserver的directory,由web1,和web2分但请求,使用random算法,处理静态请求 {.backend = web1;.weight = 2;} #设置权重为2 {.backend = web2;.weight = 5;} } director appserver random { #定义一个名为appserver的directory,由app1,和app2分但请求,使用random算法,处理动态请求 {.backend = app1;.weight = 2;} {.backend = app2;.weight = 5;} } ############定义Acl############## acl purgers { #设置清理缓存的IP "127.0.0.1"; "172.16.10.0"/16; } ############vcl_recv函数段############## sub vcl_recv { #使得后端服务能记录访问者的真实IP if (req.http.x-forwarded-for) { #添加首部信息 set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip; } else { set req.http.X-Forwarded-For = client.ip; } #配置动静分离 if (req.url ~ "\.php$"){ set req.backend = appserver; #php结尾的交给appserver服务器组处理,否则交给webserver服务器组处理 }else{ set req.backend = webserver; } #不正常的访问不缓存 if (req.request != "GET" && req.request != "HEAD" && req.request != "PUT" && req.request != "POST" && req.request != "TRACE" && req.request != "OPTIONS" && req.request != "DELETE") { /* Non-RFC2616 or CONNECT which is weird. */ return (pipe); } if (req.request != "GET" && req.request != "HEAD") { /* We only deal with GET and HEAD by default */ return (pass); } #不缓存认证信息和Cookie if (req.http.Authorization || req.http.Cookie) { /* Not cacheable by default */ return (pass); } #定义清楚缓存IP,调用上面的Acl if (req.request == "PURGE"){ #使用PURGE命令清除缓存 if(!client.ip ~ purgers){ #非ACl定义的IP,则不能清除缓存 error 405 "Method not allowed"; } return (lookup); } #支持压缩功能 if (req.http.Accept-Encoding) { if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg)$") { # No point in compressing these remove req.http.Accept-Encoding; } else if (req.http.Accept-Encoding ~ "gzip") { set req.http.Accept-Encoding = "gzip"; } else if (req.http.Accept-Encoding ~ "deflate") { set req.http.Accept-Encoding = "deflate"; } else { remove req.http.Accept-Encoding; } } } ############vcl_hit函数段############## sub vcl_hit { if (req.request == "PURGE"){ #请求方法是PURGE,这清理缓存 purge; error 200 "Purged"; } } ############vcl_miss函数段############## sub vcl_miss { if (req.request == "PURGE"){ purge; error 404 "Not in cache"; } } ############vcl_pass函数段############## sub vcl_pass { if (req.request == "PURGE"){ error 502 "PURGE on a passed object"; } } ############vcl_fetch函数段############## sub vcl_fetch { #定义缓存时长 if (req.request == "GET" && req.url ~ "\.html$") { set beresp.ttl = 300s; #超时时长为300秒 if (req.request == "GET" && req.url ~ "\.(png|xsl|xml|pdf|ppt|doc|docx|chm|rar|zip|bmp|jpeg|swf|ico|mp3|mp4|rmvb|ogg|mov|avi|wmv|swf|txt|png|gif|jpg|css|js|html|htm)$") { set beresp.ttl = 600s; } return (deliver); } } ############vcl_deliver函数段############## sub vcl_deliver { #定义Header标识,判断缓存是否命中 if (obj.hits > 0) { set resp.http.X-Cache = "HIT"; #命中则返回HIT } else { set resp.http.X-Cache = "MISS"; #未命中则返回MISS } }
3、4启动Varnish服务
/etc/init.d/varnish start
4、访问测试(查看是否命中)
222132184.png
缓存命中率的高低,直接反映Varnish的运行状态,以下通过varnishstat命令查看状态信息
[root@nginx2 varnish]# varnishstat itrate ratio: 1 1 1 Hitrate avg: 0.6771 0.6771 0.6771 368 0.00 0.01 client_conn - Client connections accepted 824 0.00 0.02 client_req - Client requests received 369 0.00 0.01 cache_hit - Cache hits 176 0.00 0.01 cache_miss - Cache misses 95 0.00 0.00 backend_conn - Backend conn. success 83 0.00 0.00 backend_unhealthy - Backend conn. not attempted 33 0.00 0.00 backend_fail - Backend conn. failures 260 0.00 0.01 backend_reuse - Backend conn. reuses 51 0.00 0.00 backend_toolate - Backend conn. was closed 315 0.00 0.01 backend_recycle - Backend conn. recycles 222 0.00 0.01 fetch_length - Fetch with Length 20 0.00 0.00 fetch_chunked - Fetch chunked 96 0.00 0.00 fetch_304 - Fetch no body (304) 16 . . n_sess_mem - N struct sess_mem 3 . . n_objectcore - N struct objectcore 3 . . n_objecthead - N struct objecthead 4 . . n_waitinglist - N struct waitinglist 4 . . n_vbc - N struct vbc 100 . . n_wrk - N worker threads 100 0.00 0.00 n_wrk_create - N worker threads created 7 . . n_backend - N backends 86 . . n_expired - N expired objects 130 . . n_lru_moved - N LRU moved objects 453 0.00 0.01 n_objwrite - Objects sent with write 368 0.00 0.01 s_sess - Total Sessions 824 0.00 0.02 s_req - Total Requests 17 0.00 0.00 s_pipe - Total pipe 252 0.00 0.01 s_pass - Total pass 338 0.00 0.01 s_fetch - Total fetch 221522 0.00 6.37 s_hdrbytes - Total header bytes
注释:
Client connections accepted:表示客户端向反向代理服务器成功发送HTTP请求的总数量
Client requests received: 表示到现在为止,浏览器向反向代理服务器发送HTTP请求的累积次数,由于可能会使用长连接,所以这个值一般会大 于“Client connections accepted”。
Cache hits:表示反向代理服务器在缓存区中查找并且命中缓存的次数。
Cache misses:表示直接访问后端主机的请求数量,也就是非命中数。
N struct object:表示当前被缓存的数量。
N expired objects:表示过期的缓存内容数量。
N LRU moved objects:表示被淘汰的缓存内容个数
二、Varnish 管理
1、手动清除缓存
[root@nginx2 varnish]# curl -X PURGE http://172.16.10.2/index.html <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html> <head> <title>200 Purged</title> </head> <body> <h1>Error 200 Purged</h1> <p>Purged</p> <h3>Guru Meditation:</h3> <p>XID: 1003529630</p> <hr> <p>Varnish cache server</p> </body> </html>
2、查看varnish日志
[root@nginx2 varnish]# varnishlog 0 Backend_health - app Still healthy 4--X-RH 8 3 8 0.011716 0.014211 HTTP/1.1 200 OK 0 Backend_health - app1 Still healthy 4--X-RH 8 3 8 0.016078 0.014856 HTTP/1.1 200 OK
3、 varnishadm 命令
[root@nginx2 varnish]# varnishadm varnish> help 200 help [command] ping [timestamp] auth response quit banner status #查看状态 start #启动varnish stop #关闭varnish vcl.load <configname> <filename> #动态加载vcl vcl.inline <configname> <quoted_VCLstring> vcl.use <configname> #动态使用vcl vcl.discard <configname> vcl.list #查看使用的vcl vcl.show <configname> #查看vcl的配置 param.show [-l] [<param>] param.set <param> <value> panic.show panic.clear storage.list backend.list backend.set_health matcher state ban.url <regexp> ban <field> <operator> <arg> [&& <field> <oper> <arg>]... ban.list
三、Varnish性能优化
Varnish有许多参数,虽然大多数场景中这些参数的默认值都可以工作得很好,然而特定的工作场景中要想有着更好的性能的表现,则需要调整某些参数。可以在管理接口中使用param.show命令查看这些参数,而使用param.set则能修改这些参数的值。然而,在命令行接口中进行的修改不会保存至任何位置,因此,重启varnish后这些设定会消失。此时,可以通过启动脚本使用-p选项在varnishd启动时为其设定参数的值。然而,除非特别需要对其进行修改,保持这些参数为默认值可以有效降低管理复杂度,由于Varnish的参数有很多,此处指对影响较大的参数进行介绍需要更加详细的介绍需查看官方文档
[root@nginx2 varnish]# varnishadm varnish> param.show listen_depth 1024 [connections] lru_interval 2 [seconds] thread_pool_max 1000 [threads] thread_pool_min 50 [threads] thread_pool_timeout 120 [seconds] thread_pools 2 [pools] varnish>
注释:
thread_pools: 用来设置线程池的数量,一般认为这个值和系统CPU的数目相同最好,设置过多的pools,varnish的并发处理能力会更强,但是也会消耗更多的CPU和内存。
thread_pool_min:用来设置每个pools的最小threads数,当pools接收到可用的请求后,就会将请求分配给空闲的threads来处理。
thread_pool_max:表示所有pools对应的threads数总和的最大值,此值不能太大,可以设置为系统峰值的90%左右即可,设置过大,会导致进程hung住。
thread_pool_timeout:表示threads的超时过期时间,当threads数大于thread_pool_min设定值时,threads空闲超过thread_pool_timeout设定的时间时,thread就会被释放 掉。
lru_interval 20 [seconds]
listen_depth 1024 [connections]
lru_interval:这是个时间参数,大概意思是说如果有一个对象在内存中超过了此参数设定的时间还没有被重用时,就把这个对象从LRU(Least Recently Used)队列中移除。 这其实是 缓存系统的一个常用算法,合理的设置这个时间,可以提高系统的运行效率。
listen_depth:这个参数是设置TCP连接队列的长度,设置大一点可以提高并发处理能力。
对于这些优化参数,最好的方式是加到varnish的启动脚本中,通过varnishd的“-p”参数调用即可。