app3:172.16.0.54
varnish 简介
安装配置varnish
name=Varnish 3.0 for Enterprise Linux el6 - $basearch
baseurl=http://repo.varnish-cache.org/redhat/varnish-3.0/el6/$basearch
enabled=1
gpgcheck=0
#gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-VARNISH
[root@varnish1 ~]# yum install varnish-3.0.4 -y [root@varnish1 ~]# vim /etc/sysconfig/varnish #varnish 的配置文件 NFILES = 131072 #打开的最大文件数 MEMLOCK = 82000# 82M,日志使用的共享内存 NPROCS = "unlimited" #最大的线程数 RELOAD_VCL = 1 # 每次重启都重新编译加载vcl。 VARNISH_VCL_CONF=/etc/varnish/default.vcl #默认使用的vcl文件 VARNISH_LISTEN_PORT=80 # vanish 监听的端口 VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1 # VARNISH_ADMIN_LISTEN_PORT=6082# varnish 管理监听的ip和端口 VARNISH_SECRET_FILE=/etc/varnish/secret #varnish 管理的 秘钥文件 VARNISH_MIN_THREADS=50 #varnish 启动的最小线程数 VARNISH_MAX_THREADS=1000 #最大线程数 VARNISH_THREAD_TIMEOUT=120 # 线程的超时过期时间,线程空闲超过设定的时间,线程就会被释放掉。 #VARNISH_STORAGE_FILE=/var/lib/varnish/varnish_storage.bin #varnish 使用文件来存储 #VARNISH_STORAGE_SIZE=1G #使用多大的文件 VARNISH_MEMORY_SIZE=100M #varnish 使用内存来存储 VARNISH_STORAGE="malloc,${VARNISH_MEMORY_SIZE}" #varnish使用malloc方式来缓存。 #VARNISH_STORAGE="file,${VARNISH_STORAGE_FILE},${VARNISH_STORAGE_SIZE}" #varnish使用file的方式缓存。 VARNISH_TTL=120 #缺省TTL DAEMON_OPTS="-a ${VARNISH_LISTEN_ADDRESS}:${VARNISH_LISTEN_PORT} \ -f ${VARNISH_VCL_CONF} \ -T ${VARNISH_ADMIN_LISTEN_ADDRESS}:${VARNISH_ADMIN_LISTEN_PORT} \ -t ${VARNISH_TTL} \ -w ${VARNISH_MIN_THREADS},${VARNISH_MAX_THREADS},${VARNISH_THREAD_TIMEOUT} \ -u varnish -g varnish \ -S ${VARNISH_SECRET_FILE} \ -s ${VARNISH_STORAGE}"
#######################################################################
[root@varnish1 ~]# vim /etc/varnish/default.vcl #vcl的配置文件 probe staticcheck { .url = "/test.html"; #请求的url .interval = 60s; #探测的周期 .timeout = 3s; # 每次探测的过期时长 .window = 8; #基于最近多少次的探测进行,默认是8; .threshold = 4; #在.window中指定的次数中,至少有多少次是成功的才判定后端主机正健康运行; .initial = 3; #Varnish启动时对后端主机至少需要多少次的成功探测,默认同.threshold; .expected_response = 200; #期望后端主机响应的状态码,默认为200; } #健康状态检查,检查静态 probe dycheck { .url = "/test.php"; .interval = 60s; .timeout = 3s; .window = 8; .threshold = 4; .initial = 3; .expected_response = 200; } #健康状态检查,检查动态 backend app1 { .host = "172.16.0.52"; .port = "80"; .probe = dycheck; } backend app2 { .host = "172.16.0.54"; .port = "80"; .probe = dycheck; } backend s1 { .host = "127.0.0.1"; .port = "8080"; .probe = staticcheck; } #定义2个app主机,1个静态主机 director appservers round-robin { # .retries = 5; {.backend = app1;} {.backend = app2;} } #定义一个负载均衡组,使用round-robin算法。 acl purgers { "127.0.0.1"; "192.168.1.0"/24; } #定义 可以purge的acl。 sub vcl_recv { if (req.request == "PURGE") { if (!client.ip ~ purgers) { error 405 "Method not allowed"; } #如果client 不是本地或者是192.168.1.0/24 网段的就不允许purge。 return (lookup); } 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; } #定义后端web 可以记录真实的client的ip。 if (req.request != "GET" && req.request != "HEAD" && req.request != "PUT" && req.request != "POST" && req.request != "TRACE" && req.request != "OPTIONS" && req.request != "DELETE") { return (pipe); } #如果请求的不是get,head,put,post,trace,options,delete 就直接给pipe。 if (req.http.Authenticate || req.http.Authorization) { return (pass); } #请求的有认证信息的,直接给pass,交给后端处理。 if (req.request != "GET" && req.request != "HEAD"){ return (pass); }# 请求的不是get,head方法,直接给pass,交给后端处理。 if (req.url ~ "^/$") { unset req.http.cookie; } #把首页去掉cookie。 if (req.url ~ "^/[^?]+\..(jpeg|jpg|png|gif|bmp|tif|tiff|ico|wmf|js|css|ejs|swf|txt|zip|exe|html|htm)(\?.*|)$") { unset req.http.cookie; set req.url = regsub (req.url,"\?.*$",""); #去掉Query Stings if (req.http.Accept-Encoding){ if (req.url ~ "\.(jpg|png|gif|jpeg|)") { remove req.http.Accept-Encoding; } elseif (req.http.Accept-Encoding ~ "gzip") { set req.http.Accept-Encoding = "gzip"; }elseif (req.http.Accept-Encoding ~ "deflate") { set req.http.Accept-Encoding = "deflate"; }else{ remove req.http.Accept-Encoding; }# 静态文件的压缩处理 } return (lookup); } if (req.url ~ "\.(php|cgi)($|\?)"){ set req.backend = appservers; return (pass); #是动态文件交给后端appservers处理 } else { set req.backend = s1; return (lookup); #静态文件交个s1处理 } } sub vcl_hash { hash_data(req.url); if (req.http.host) { hash_data(req.http.host); } else { hash_data(server.ip); } if (req.http.Accept-Encoding ~ "gzip") { hash_data("gzip"); } elseif (req.http.Accept-Encoding ~ "deflate") { hash_data("deflate"); } return (hash); #对Accept-Encoding 进行hash } sub vcl_hit { if (req.request == "PURGE") { purge; error 200 "Purged"; } # 请求是purge的 就返回200,成功。 } sub vcl_miss{ if (req.request == "PURGE") { purge; error 404 "NOT in cache"; } #请求 是purge,返回404. } sub vcl_pass { if (req.request == "PURGE") { error 502 "PURGE on a passed object"; } #请求是purge,返回502. } sub vcl_fetch { if (req.url ~ "^/$") { unset beresp.http.set-cookie; } #对应主页去除cookie。 if (beresp.status == 500 || beresp.status == 501 || beresp.status == 502 || beresp.status ==503 || beresp.status ==504) { set beresp.saintmode = 20s; return (restart); } # 如果status是500,501,502,503,504,则启动saintmode。 if (beresp.http.Pragma ~ "no-cache" || beresp.http.Cache-Control ~ "no-cache" || beresp.http.Cache-Control ~ "private" ) { return (hit_for_pass); } if (beresp.http.Set-Cookie || beresp.ttl <= 0s || beresp.Vary == "*" ) { set beresp.ttl = 120s; return (hit_for_pass); } if (req.request == "GET" && req.url ~ "\.(html|ejs|jpg|jpeg|png|xsl|xml|swf|ico|gif|css|js|htm)$") { set beresp.ttl = 600s; } if (req.request == "GET" && req.url ~ "^/[^?]+\.(css|js|gif|jpg|jpeg|bmp|png|tiff|tif|ico|swf|exe|zip|bmp|wmf)(\?.*|)$" ) { set beresp.ttl = 300s; } if (!req.backend.healthy){ set req.grace = 1m; } return (deliver); } sub vcl_deliver { if (obj.hits > 0) { set resp.http.X-Cache = "HIT from" + " " + server.ip; } else { set resp.http.X-Cache = "miss"; } return (deliver); }
[root@varnish1 ~]# /etc/init.d/varnish start [root@varnish1 ~]# varnishlog 0 CLI - Wr 200 19 PONG 1397943276 1.0 0 Backend_health - s1 Still healthy 4--X-RH 8 4 8 0.000689 0.001174 HTTP/1.1 200 OK 0 Backend_health - app1 Still healthy 4--X-RH 8 4 8 0.033177 0.010798 HTTP/1.1 200 OK 0 Backend_health - app2 Still healthy 4--X-RH 8 4 8 0.003488 0.003647 HTTP/1.1 200 OK 0 CLI - Rd ping 0 CLI - Wr 200 19 PONG 1397943279 1.0 会看到 健康状态检查的。
检测varnish
第一次访问,查看x-cache 是miss的。第二次访问如下图
可以看到是 X-Cache:HIT from 192.168.1.151
使用varnishstat
命中率还是蛮高的哦
测试下purge:
防盗链配置:
在vcl_recv中添加: if (req.http.referer ~ "http://.*") { if (!(req.http.referer ~ "http://.*\.baidu\.com" || req.http.referer ~ "http://.*\.google\.com.*" || req.http.referer ~ "http://.*\.sogou\.com" || req.http.referer ~ "http://.*\.soso\.com" || req.http.referer ~ "http://.*\.so\.com")) { set req.http.host = "www.mytest.com"; set req.url = "/templets/default/p_w_picpaths/logo.gif"; } return (lookup); }
不缓存大文件(比如大于10M)
sub vcl_recv { if (req.http.x-pipe && req.restarts > 0) { remove req.http.x-pipe; return (pipe); } } sub vcl_fetch { if (beresp.http.Content-Length ~ "[0-9]{7,}") { set req.http.x-pipe = "1"; return (restart); } }
本文没有介绍DZ的安装,以及nginx的配置。nginx记录client的真实ip配置:
log_format mylogformat ' $http_x_forwarded_for- $remote_user [$time_local] ' ' "$request" ' ' "$http_referer" "$http_user_agent" '; access_log /var/log/nginx/access3_log mylogformat;