vim /usr/local/varnish3.0/etc/varnish/default.vcl #设置后端服务 backend linuxidc { .host = "192.168.100.5"; .port = "80"; .connect_timeout = 1s; .first_byte_timeout = 5s; .between_bytes_timeout = 2s; } backend 88181 { .host = "192.168.100.6"; .port = "80"; .connect_timeout = 1s; .first_byte_timeout = 5s; .between_bytes_timeout = 2s; } #定义负载均衡 director lb_test random { { .backend = linuxidc; .weight = 5; } { .backend = 88181; .weight = 5; } } #定义访问控制列表 acl purge { "localhost"; "127.0.0.1"; "192.168.100.0"/24; "192.168.0.0"/24; } sub vcl_recv { #开启压缩模式,图片格式取消压缩 if (req.http.Accept-Encoding) { if (req.url ~ "\.(jpg|png|gif|jpeg|flv)" ) { remove req.http.Accept-Encoding; remove req.http.Cookie; } 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; } } #根据host设置后端服务器 if (req.http.Host ~ "(?i)(www.linuxidc.com|www.88181.com)") { set req.backend = lb_test; }else if (req.http.Host ~ "(?i)image.Android.com"){ set req.backend = linuxidc; }else { error 408 "Hostname not found"; } #如果为purge请求,客户端ip不在访问列表中,返回405拒绝 if (req.request == "PURGE") { if (!client.ip ~purge) { error 405 "Not Allowed"; } #本地缓存查找 return(lookup); } #如果为GET请求,url后缀为jpg,png,gif等 取出cookie if (req.request == "GET"&&req.url ~ "(?i)\.(jpg|png|gif|swf|jpeg|ico)$") { unset req.http.cookie; } #如果GET请求,url为php,则穿过cache,不缓存 if (req.request =="GET"&&req.url ~ "(?i)\.php($|\?)"){ return (pass); } #简单防盗链 if (req.http.referer ~ "http://.*") { if ( !(req.http.referer ~ "http://.*linuxidc\.com" || req.http.referer ~ "http://.*88181\.com" || req.http.referer ~ "http://.*android\.com" || req.http.referer ~ "http://.*google\.com" || req.http.referer ~ "http://.*baidu\.com" || req.http.referer ~ "http://.*yahoo\.cn" )) { error 404 "Not Found!"; } } #获取客户端ip # if (req.restarts == 0) { 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; } # } #不是以下请求进入pipe模块 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); } #不是GET 和HEAD请求不缓存 if (req.request != "GET" && req.request != "HEAD") { /* We only deal with GET and HEAD by default */ return (pass); } if (req.http.Authorization) { /* Not cacheable by default */ return (pass); } return (lookup); } # sub vcl_pipe { return (pipe); } # sub vcl_pass { return (pass); } #使用url+host hash算法查找数据 sub vcl_hash { hash_data(req.url); if (req.http.host) { hash_data(req.http.host); } else { hash_data(server.ip); } return (hash); } # 如果请求为purge 将清除缓存 sub vcl_hit { if (req.request == "PURGE") { set obj.ttl = 0s; error 200 "Purged"; } return (deliver); } sub vcl_miss { return (fetch); } # sub vcl_fetch { if (beresp.ttl <= 0s || beresp.http.Set-Cookie || beresp.http.Vary == "*") { /* * Mark as "Hit-For-Pass" for the next 2 minutes */ set beresp.ttl = 0 s; return (hit_for_pass); } if (beresp.http.Pragma ~"no-cache" || beresp.http.Cache-Control ~"no-cache" || beresp.http.Cache-Control ~"private") { return (deliver); } #为特定格式文件设置缓存时间 if (req.request == "GET"&&req.url ~ "(?i)\.(js|css|mp3|jpg|png|gif|swf|jpeg|ico)$") { set beresp.ttl = 30d; } if (req.request == "GET"&&req.url ~ "(?i)\.(html|htm)$") { set beresp.ttl = 1d; } return (deliver); } # 设置返回状态 sub vcl_deliver { set resp.http.x-hits = obj.hits; if (obj.hits > 0) { set resp.http.X-Cache = "Hit test.com"; }else { set resp.http.X-Cache = "Miss test.com"; } set resp.http.Server = "BWM"; return (deliver); } # 定义错误 sub vcl_error { set obj.http.Content-Type = "text/html; charset=utf-8"; set obj.http.Retry-After = "5"; synthetic {" <?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>"} + obj.status + " " + obj.response + {"</title> </head> <body> <h1>Error "} + obj.status + " " + obj.response + {"</h1> <p>"} + obj.response + {"</p> <h3>Guru Meditation:</h3> <p>XID: "} + req.xid + {"</p> <hr> <p>Varnish cache server</p> </body> </html> "}; return (deliver); } sub vcl_init { return (ok); } sub vcl_fini { return (ok); } 四、启动 启动命令 /usr/local/varnish3.0/sbin/varnishd -f /usr/local/varnish3.0/etc/varnish/default.vcl -s malloc,2G -a 0.0.0.0:80 -w 1024,51200,10 -t 3600 -T 192.168.100.2:3500 检测配置文件是否存在错误 /usr/local/varnish3.0/sbin/varnishd -C -f /usr/local/varnish3.0/etc/varnish/default.vcl 参数 -a address:port 监听端口 -f 指定配置文件 -s 指定缓存类型 malloc为内存, file 文件缓存 -t 默认TTL -T address:port 管理端口 -w 最小线程,最大线程,超时时间 记录varnish日志 /usr/local/varnish3.0/bin/varnishncsa -w /var/logs/varnish.log & 五、缓存刷新 php脚步如下 <?php function purge($ip, $url) { $errstr = ''; $errno = ''; $fp = fsockopen ($ip, 80, $errno, $errstr, 2); if (!$fp) { return false; } else { $out = "PURGE $url HTTP/1.1\r\n"; $out .= "Host:image.android.com\r\n"; $out .= "Connection: close\r\n\r\n"; fputs ($fp, $out); $out = fgets($fp , 4096); fclose ($fp); return true; } } if(isset($_POST['content'])) { //$str=str_replace("\r","<br>",$_POST[content]); $arr=(explode("\n",$_POST['content'])); $Server="192.168.100.2"; foreach ($arr as $value) { echo $value; purge($Server, $value); echo "刷新成功"."<br />"; } //purge($Server, "$_POST[content]"); //echo "刷新成功"; } ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>varnish缓存刷新</title> </head> <body> <form action="?" method="post"> 填写需要刷新url<br /> <textarea name="content" cols="40" rows="10"></textarea> <input type="submit" value="submit" /> </form> </body> </html> ########### 通过管理端口清除缓存 telnet 192.168.100.2 3500 3.0版本 为ban.url aaaa.html 2.版本为purge.url aaaa.html |