一个很完整的Varnish vcl文件

发布时间:2020-09-09编辑:脚本学堂
一个很完整的Varnish vcl文件,初学varnish配置的朋友不妨看看这个。

一个很完整的varnish vcl文件,初学varnish配置的朋友不妨看看这个。

复制代码 代码如下:

include "vhost/au92.vcl";

#允许刷新缓存的 ip
acl purgeAllow {
  "127.0.0.1";
  "172.16.101.33";
}

#/acl iplist

sub vcl_recv {
#虚拟站点
include "vhost/sites.vcl";

set req.grace = 5m;
#判断如果不是 acl purgeAllow 定义的 IP
if (req.request == "PURGE") {
  if (client.ip !~ purgeAllow) { #判断是否允许 ip,如果不是,是不可以刷缓存的,返回 405
    error 405 "Not allowed.";
  }
  #去缓存中查找
  return (lookup);
}

#首次访问增加 X-Forwarded-For 头信息,方便后端程序获取客户端 ip
if (req.restarts == 0) {
  #如果设置过此 header 则要再次附加上,用,隔开,如果
  #只有一层代理的话,就无需设置了
  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;
  }
}

#至单独服务器下,减少动态应用服务器压力,同时降低 varnishd 的压力
if(req.url ~ ".(php)$"){
  return (pass);
}

#非正规的请求直接转发给后端服务器
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 请求,如果你不想缓存 POST 的页面话
if (req.request != "GET" && req.request != "HEAD") {
  return (pass);
}

#http 认证的页面也 pass
if (req.http.Authorization) {
  return (pass);
}

#admin目录pass
if (req.url ~ "^/admin" && req.url !~ ".(gif|jpg|swf|css|js|png|jpg|jpeg|gif|png|tiff|tif|svg|swf|ico|doc|ppt|pps|xls|odc|odb|odf|odg|odi|odp|ods|odt|sxc|sxd|sxi|sxw|txt)") {
  return (pass);
}

return (lookup);
}
#/sub vcl_recv

#管道?按官方文档说的是此模式下请求会原封不动的转交给后端直到连接关闭
sub vcl_pipe {
  return (pipe);
}
#/sub vcl_pipe

#交给后端服务器
sub vcl_pass {
  return (pass);
}
#/sub vcl_pass

#缓存文件名的哈希处理
sub vcl_hash {
  hash_data(req.url);
  if (req.http.host) {
    hash_data(req.http.host);
  } else {
    hash_data(server.ip);
  }
  return (hash);
}
#/sub vcl_hit

#缓存命中后的处理
sub vcl_hit {
  if (req.request == "PURGE") {
    purge;
    error 200 "Purged.";
  }
  return (deliver);
}
#/sub vcl_hit

#缓存未命中
sub vcl_miss {
  #更新缓存的请求,提示缓存不存在 Not in cache
  if (req.request == "PURGE") {
    error 404 "Not in cache.";
  }
  #既然缓存不存在了,就去后端取吧
  return (fetch);
}
#/sub vcl_miss

sub vcl_fetch {
  if (req.request == "GET" && req.url ~ ".(gif|jpg|swf|css|js|png|jpg|jpeg|gif|png|tiff|tif|svg|swf|ico|doc|ppt|pps|xls|odc|odb|odf|odg|odi|odp|ods|odt|sxc|sxd|sxi|sxw|txt)") {
    remove beresp.http.Set-Cookie;
    set beresp.ttl = 30 d;
  }
  include "vhost/extend.vcl";

  if (beresp.ttl <= 0s || beresp.http.Set-Cookie || beresp.http.Vary == "*") {
    /*
    * Mark as "Hit-For-Pass" for the next 2 minutes
    */
    set beresp.ttl = 120 s;
    return (hit_for_pass);
  }
  #404,300 页面不缓存
  if (beresp.status == 404 || beresp.status == 300) {
    error 404;
  }
  return (deliver);
}
#/sub vcl_fetch

#发送给客户端
sub vcl_deliver {
  if (obj.hits > 0) {
    set resp.http.X-Cache = "HIT";
    #统计命中了多少次
    set resp.http.X-Cache-Hits = obj.hits;
  } else {
    set resp.http.X-Cache = "MISS";
  }
  #去掉 varnish 中的一些头信息(如果你不想保留的话,建议保留 Age,方便查看)
  remove resp.http.X-Varnish;
  remove resp.http.Via;
  return (deliver);
}
#/sub vcl_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>
            <hr>
          </body>
      </html>
        "};
        return (deliver);
}
#/sub vcl_error

sub vcl_init {
  return (ok);
}
#/sub vcl_init

sub vcl_fini {
  return (ok);
}
#/sub vcl_fini