一张图概括varnish weir 2016-03-24 15:21:43.0 varnish 2158 import std; ##在需要输出日志的地方,使用 std.log 即可:std.log("LOG_DEBUG: URL=" + req.url); ##这样的话,就可以通过日志了解varnish的工作流程,很方便的优化啦,效率何止提高十倍! backend b1 { .host = "127.0.0.1"; .port = "8080"; .connect_timeout = 1s; ##等待连接后端的时间 .first_byte_timeout = 5s; ##等待从backend传输过来的第一个字符的时间 .between_bytes_timeout = 2s; ##两个字符的间隔时间 .max_connections=1000; ##可以设置连接后端服务器得最大限制数 } probe p1 { .url = "/index.jsp"; .timeout = 0.3 s; .window = 8; //要检查后端服务器的次数 .threshold = 3; //.window里面要有多少polls成功就认为后端是健康的 .initial = 3; //当varnish启动的时候,要确保多少个probe正常 } backend b2 { .host = "127.0.0.1"; .port = "9080"; .connect_timeout = 1s; .first_byte_timeout = 5s; .between_bytes_timeout = 2s; .max_connections=1000; } director d1 fallback {##选择第一个健康的backend {.backend = b1;//引用已经存在的backend } {.backend = b2; } } acl purgeallow {##访问IP控制 "127.0.0.1"; #"192.168.2.114"; } sub vcl_recv {##入口 set req.backend=d1; if(!req.backend.healthy){##后端服务器是否健康 set req.grace = 30m;##设置对象被保持的时间 }else{ set req.grace = 5s; } if(req.request == "PURGE") {##请求类型 if(!client.ip ~ purgeallow) {##不匹配设置的IP地址就不允许访问 error 405 "not allowed."; } return(lookup);##访问缓存 } if (req.request == "GET" && req.url ~ "\.(jpg|png|gif|swf|flv|ico|jpeg)$") {##图片等清除cookie unset req.http.cookie; } if (req.request =="GET" && req.url ~ "(?i)\.jsp($|\?)"){##请求是jsp等直接转到访问服务器 return (pass);##转到访问服务器 } if (req.restarts == 0) {##req.restarts 最大的重启次数 if (req.http.x-forwarded-for) {##设置真实IP 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 ~ "^.*/wei$"){##自定义需要缓存的请求 return(lookup); } if (req.request != "GET" && req.request != "HEAD" && req.request != "PUT" && req.request != "POST" && req.request != "TRACE" && req.request != "OPTIONS" && req.request != "DELETE") {##如果不能匹配这些请求,后面的请求统统直接去访问后台服务器 return (pipe); } if (req.request != "GET" && req.request != "HEAD") {##只有该请求转到服务器 return (pass); } if (req.http.Authorization || req.http.Cookie) {##不能作为缓存的请求直接转到服务器 return (pass); } return (lookup); } sub vcl_pipe { ##在这个模式,请求会被passed到后端服务器, ##在连接关闭前,无论是这个客户端还是对应的后端服务器的数据,都会进入pass模式。 return (pipe); } sub vcl_pass {##转向访问服务器 return (pass); } sub vcl_hash { hash_data(req.url);##增加一个散列值,默认hash_data() 是调用request的host和url if (req.http.host) { hash_data(req.http.host); } else { hash_data(server.ip); } return (hash); } sub vcl_hit {##请求从cache中命中需要的内容 return (deliver);##请求的目标被缓存,然后发送给客户端 } sub vcl_miss {##当需要的内容没有在缓存中命中的时候被调用,决定是否尝试到后端服务器查找目标,从哪个后端服务器查找目标 std.log("now miss url===" + req.url);##记录一下没有被命中的请求,为事后分析提供依据 return (fetch);##直接去请求服务器 } sub vcl_fetch {##在一个文件成功从后台获取后被调用,通常他的任务就是改变response headers, ##触发ESI进程,在请求失败的时候轮询其他服务器。在vcl_fetch中一样的包含请求的对象,还有返回对象beresp,它将会包含后端服务器的返回信息 set beresp.grace = 30m;##对象grace保存的时间 if(beresp.status == 500){ set beresp.saintmode = 20s;##saint模式持续的时间 return(restart);##重新再走一次请求 } if(req.url ~ "^.*/wei$"){##如果是自己自定义的请求,就保存下来,然后返回客户端 set beresp.ttl = 1m; return (deliver); } if (beresp.ttl <= 0s || beresp.http.Set-Cookie || beresp.http.Vary == "*") {##如果有这些情况的话在120s之内还是会走pass set beresp.ttl = 120 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(beresp.status == 404 || beresp.status == 300) { error 404; } if (req.request == "GET" && req.url ~ "\.(jpg|png|gif|swf|flv|ico|jpeg)$") {##图片资源保存1d set beresp.ttl = 1d; } if (req.request == "GET" && req.url ~ "\.(htm|html)$") { set beresp.ttl = 1d; } # if (req.url ~ "\.(png|gif|jpg)$") { # unset beresp.http.set-cookie; # set beresp.ttl = 1h; # } return (deliver);##缓存并返回客户端 } sub vcl_deliver { if (obj.hits > 0) {##如果已经保存过,http.X-Cache就标记为cached set resp.http.X-Cache = "cached"; } else { set resp.http.x-Cache = "uncached"; } #X-Powered-By是网站响应头信息其中的一个,出于安全的考虑,一般会修改或删除掉这个信息。 unset resp.http.X-Powered-By; unset resp.http.Server; return (deliver); } sub vcl_error {##当hit错误或者是发生内部错误的时候 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); }