为什么 Varnish 中的平均缓存命中率很低?

为什么 Varnish 中的平均缓存命中率很低?

有人知道为什么使用 Wordpress(使用 Varnish 和 Nginx)时平均缓存命中率非常低吗?

Varnish 统计数据显示:

命中率:10 100 518 命中率平均值:0.4143 0.2690 0.1948

知道如何修复此问题吗?我的 varnish default.vcl 是:

# This is a basic VCL configuration file for varnish.  See the vcl(7)
# man page for details on VCL syntax and semantics.
#
# Default backend definition.  Set this to point to your content
# server.
#
backend default {
    .host = "77.81.240.177";
    .port = "8080";
}

acl purge {
    "77.81.240.177";
}

sub vcl_recv {

    # Add a unique header containing the client address
    remove req.http.X-Forwarded-For;
    #set    req.http.X-Forwarded-For = client.ip;
    set    req.http.X-Forwarded-For = req.http.rlnclientipaddr;    

    # Let's make sure we aren't compressing already compressed formats.
    if (req.http.Accept-Encoding) {
        if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|mp3|mp4|m4v)(\?.*|)$") {
            remove req.http.Accept-Encoding;
        } elsif (req.http.Accept-Encoding ~ "gzip") {
            set req.http.Accept-Encoding = "gzip";
        } elsif (req.http.Accept-Encoding ~ "deflate") {
            set req.http.Accept-Encoding = "deflate";
        } else {
            remove req.http.Accept-Encoding;
        }
    }

    if (req.request == "PURGE") {
        if (!client.ip ~ purge) {
            error 405 "Not allowed.";
        }
        return(lookup);
    }

    if (req.url ~ "^/$") {
        unset req.http.cookie;
    }
}

sub vcl_hit {
    if (req.request == "PURGE") {
        set obj.ttl = 0s;
        error 200 "Purged.";
    }
}

sub vcl_miss {
    if (req.request == "PURGE") {
        error 404 "Not in cache.";
    }

    if (!(req.url ~ "wp-(login|admin)")) {
        unset req.http.cookie;
    }

    if (req.url ~ "^/[^?]+.(jpeg|jpg|png|gif|ico|js|css|txt|gz|zip|lzma|bz2|tgz|tbz|html|htm)(\?.|)$") {
        unset req.http.cookie;
        set req.url = regsub(req.url, "\?.$", "");
    }

    if (req.url ~ "^/$") {
        unset req.http.cookie;
    }
}

sub vcl_fetch {
    if (req.url ~ "^/$") {
        unset beresp.http.set-cookie;
    }

    if (!(req.url ~ "wp-(login|admin)")) {
        unset beresp.http.set-cookie;
    }

    if (req.url ~ "^/w00tw00t") {
        error 403 "Not permitted";
    }
}

答案1

一个好的方法是用 varnishlog 检查流量以查看是什么使得哪些规则适用。

由于您没有强制执行 TTL,我猜测 wordpress 网站会提供 Cache-Control 标头,例如“max-age:0”或“no-cache”、“private”等,并且 varnish 会遵守此类标头,除非您明确告诉它不要这样做,即:

 sub vcl_fetch {
     if (!(req.url ~ "wp-(login|admin)")) {
         unset beresp.http.set-cookie;
         set beresp.ttl = 3600s;
     }

vcl_fetch 中的第一个规则没有意义,因为第二个规则将取消设置除 wp-login/wp-admin 之外的所有 URL 的所有 set-cookie。


向 vcl_deliver 添加一些配置以输出标头,说明是否命中:

sub vcl_deliver {
        if (obj.hits > 0) {
                set resp.http.X-Cache = "HIT";
        } else {
                set resp.http.X-Cache = "MISS";
        }
     return (deliver);
}

对您的配置的其他反馈:

在 vcl_recv 中,如果 url 不是 wp-login 或 wp-admin,则执行“unset req.http.cookie”,这意味着如果用户登录 /wp-login 然后转到“/”,您将取消设置他的 cookie。您只需要在 vcl_recv 中取消设置那些永远不需要 cookie 的 url,即 .(js|css|png|jpg) 等,并在 vcl_fetch 中删除设置的 cookie。

答案2

wp-varnish

查看wp-varnish- WordPress 的一个插件,当 WordPress 中的内容发生更改时,它会清除 Varnish 中的内容。它还附带一个示例 VCL,可以为您提供更好的命中率

示例 VCL

backend default {
  .host = "127.0.0.1";
  .port = "8080";
}

acl purge {
  "localhost";
}

sub vcl_recv {
  if (req.request == "PURGE") {
    if(!client.ip ~ purge) {
      error 405 "Not allowed.";
    }
    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.url ~ "wp-(login|admin)" || req.url ~ "preview=true") {
    return (pass);
  }

  remove req.http.cookie;
  return (lookup);
}

sub vcl_hit {
  if (req.request == "PURGE") {
    purge;
    error 200 "Purged.";
  }
}

sub vcl_miss {
  if (req.request == "PURGE") {
    purge;
    error 200 "Purged.";
  }
}

sub vcl_fetch {
  if (req.url ~ "wp-(login|admin)" || req.url ~ "preview=true") {
    return (hit_for_pass);
  }

  set beresp.ttl = 24h;
  return (deliver);
}

相关内容