网上收集、整理的Varnish 4.0 高命中率配置示例:

[root@node1 varnish]# cat  web.vcl 
#
# This is an example VCL file for Varnish.
#
# It does not do anything by default, delegating control to the
# builtin VCL. The builtin VCL is called when there is no explicit
# return statement.
#
# See the VCL chapters in the Users Guide at https://www.varnish-cache.org/docs/
# and http://varnish-cache.org/trac/wiki/VCLExamples for more examples.

# Marker to tell the VCL compiler that this VCL has been adapted to the
# new 4.0 format.
vcl 4.0;

# Default backend definition. Set this to point to your content server.
probe backend_health_check {
    .url = "/";
    .interval = 10s;
    .window = 5 ;
    .threshold = 3;
}
backend web1 {
    .host = "172.16.1.51";
    .port = "80";
    .probe = backend_health_check ;
}
backend web2 {
    .host = "172.16.1.52";
    .port = "80";
    .probe = backend_health_check ;
}

import directors;
sub vcl_init {
    new  web_cluster = directors.random();
    web_cluster.add_backend(web1,1);
    web_cluster.add_backend(web2,2);
}
acl purges {
    "localhost";
}

sub vcl_recv {
    # Happens before we check if we have this in cache already.
    #
    # Typically you clean up the request here, removing cookies you don't need,
    # rewriting the request, etc.
    #判断请求主机、转发至后端服务器,若需要支持后端虚拟主机,也可在此设置
    if(req.http.host ~ "(?i)(.*)hurn\.com") {
    set req.backend_hint = web_cluster.backend();
    } else {
    return (synth( 408 ,"Host Not Found"));
        }
    #定义缓存修剪
    if(req.method == "PURGE") {
        if(!client.ip ~ purges) {
            return (synth(403,"Not Allow Purge"));
            }
        return(purge);
    }
    #定义到收到无法理解的请求时,如何处理
    if( req.method != "GET" && 
    req.method != "HEAD" &&
    req.method != "PUT" &&
    req.method != "POST" &&
    req.method != "TRACE" &&
    req.method != "OPTIONS" &&
    req.method != "DELETE" ) {
    return(pipe);
        }

    #定义缓存类型,如果不是GET、HEAD方式都不缓存
    if(req.method != "GET" || req.method != "HEAD" ) {
    return(pass);
    }
    #如果有认证头部,也不缓存
    if(req.http.Authorization) {
    return(pass);
    }
    #清除客户端发送至后端服务器时公共文件的cookie
    if (req.url ~ "(?i)(.*)\.(jpg|png|gif|jpeg|flv|bmp|gz|tgz|bz2|tbz|js|css|html|htm)($|\?)") {
    unset req.http.Cookie;
    }
    #不缓存带Cookie的文件,js,css都带Cookie,如果需要可缓存
    if(req.http.Cookie) {
    return(pass);
    }
    #定义特殊目录不缓存:
    if(req.url ~ "^/admin" || req.url ~ "^/login" ){
    return(pass);
    }
    #动态内容不缓存,直接发往后端服务器
    if(req.url ~ "(?i)(.*)\.(php|jsp|aspx)($|.*)") {
    return(pass);
    }
    #设置X-Forward-For 记录客户端的IP,方便后端服务器记录日志
    if(req.http.X-Forward-For) {
    set req.http.X-Forward-For = req.http.X-Forward-For + " , " + client.ip ;
    } else {
    set req.http.X-Forward-For = client.ip ;
    }   
    #Accept-Encoding 是浏览器发给服务器,声明浏览器支持的编码类型的  
    #修正客户端的Accept-Encoding头信息 
    #防止个别浏览器发送类似 deflate, gzip 
    if (req.http.Accept-Encoding) { 
        if (req.url ~ "^(.*)\.(jpg|png|gif|jpeg|flv|bmp|gz|tgz|bz2|tbz)($|\?)" ) { 
            unset 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 if (req.http.Accept-Encoding ~ "sdch"){ 
            #chrome新增加的压缩 
            set req.http.Accept-Encoding = "sdch"; 
        }else { 
            unset req.http.Accept-Encoding; 

        } 
    }         
    #剩余内容都去查缓存
    return(hash);
}
#定义清理缓存
sub vcl_purge {
    return(synth(200,"Purged"));
}
sub vcl_backend_response {
    # Happens after we have read the response headers from the backend.
    #
    # Here you clean the response headers, removing silly Set-Cookie headers
    # and other mistakes your backend does.
    #如果请求的是动态页面直接发转发 
    #动态请求回来的,一定要放在前面处理 
    if (bereq.url ~ "^(.*)\.(php|jsp|do|aspx|asmx|ashx)($|.*)") { 
        set beresp.http.Cache-Control="no-cache, no-store"; 
        unset beresp.http.Expires; 
        return (deliver); 
    }
    # 仅当该请求可以缓存时,才设置beresp.grace,若该请求不能被缓存,则不设置beresp.grace 
    if (beresp.ttl > 0s) { 
        set beresp.grace = 10m; 
    }
   #设置从后台服务器获得的特定格式文件的缓存TTL    
 if (bereq.url ~ "^(.*)\.(pdf|xls|ppt|doc|docx|xlsx|pptx|chm|rar|zip)($|\?)")      
    { 
        #移除服务器发送的cookie  
        unset beresp.http.Set-Cookie; 
        #加上缓存时间 
        set beresp.ttl = 30d; 
        return (deliver); 
    }else if(bereq.url ~ "^(.*)\.(bmp|jpeg|jpg|png|gif|svg|png|ico|txt|css|js|html|htm)($|\?)"){ 
        #移除服务器发送的cookie  
        unset beresp.http.Set-Cookie; 
        #加上缓存时间 
        set beresp.ttl = 15d; 
        return (deliver); 
    } else if(bereq.url ~ "^(.*)\.(mp3|wma|mp4|rmvb|ogg|mov|avi|wmv|mpeg|mpg|dat|3pg|swf|flv|asf)($|\?)")        { 
        #移除服务器发送的cookie  
        unset beresp.http.Set-Cookie; 
        #加上缓存时间 
        set beresp.ttl = 30d; 
        return (deliver); 
        }   

       #从后台服务器返回的response信息中,没有缓存的,不缓存 
    if (beresp.http.Pragma ~"no-cache" || beresp.http.Cache-Control ~"no-cache" || beresp.http.Cache-Control ~"private") { 
            return (deliver); 
    } 
    return (deliver); 
}

sub vcl_deliver{
    # Happens when we have all the pieces we need, and are about to send the
    # response to the client.
    #
    # You can do accounting or modifying the final object here.
    #添加一个Header标识,以判断缓存是否命中。 
    if (obj.hits > 0) { 
        set resp.http.X-Cache = "HIT from cache"; 
    } else { 
        set resp.http.X-Cache = "MISS from cache"; 
    } 
    #去掉头部
    unset  resp.http.X-Varnish;
    unset  resp.http.Via;
    set    resp.http.Server = "Web Server";

}