忽略 Varnish VCL 中的 GET 参数

Jam*_*son 4 http nginx cache varnish ruby-on-rails

好的:我已经建立了一个站点,其中包含一些我们向开发人员公开的 API,它们采用以下格式

/api/item.xml?type_ids=34,35,37&region_ids=1000002,1000003&key=SOMERANDOMALPHANUM
Run Code Online (Sandbox Code Playgroud)

在这个 URI 中,type_ids 总是被设置,region_ids 和 key 是可选的。

需要注意的重要一点是,关键变量不会影响响应的内容。它用于请求的内部跟踪,因此我们可以识别发出缓慢或其他不需要的请求的人。

在 Varnish 中,我们有一个像这样的 VCL:

if (req.http.host ~ "the-site-in-question.com") {
  if (req.url ~ "^/api/.+\.xml") {
    unset req.http.cookie;
  }
}
Run Code Online (Sandbox Code Playgroud)

我们只是去除 cookie 并让后端完成其余的工作(就时间而言,这是一种 hackaround,因为 Rails/authlogic 发送带有 API 响应的会话 cookie)。

但目前,任何不同的开发人员基本上都在访问不同的缓存,因为它们&key=SOMEALPHANUM被视为 Varnish 哈希存储的一部分。这显然不是一个很好的解决方案,我正在尝试找出如何告诉 Varnish 忽略 URI 的那部分。

3mo*_*olo 6

如果您需要将key=SOMEALPHANUM完整的保留给后端以防万一不是从缓存中传递,那么最好regsubvcl_hash函数内代替,因为这不会真正改变 url,而只会改变键的哈希值。

sub vcl_hash {
  if(req.http.host ~ "the-site-in-question.com" & req.url ~ "^/api/") {
    set req.http.X-Sanitized-URL = req.url;
    set req.http.X-Sanitized-URL = regsub(req.http.X-Sanitized-URL, "&key=[A-Za-z0-9]+", "");
    set req.hash += req.http.X-Sanitized-URL;
  } else {
    set req.hash += req.url;
  }
  set req.hash += req.http.host;
  hash;
}
Run Code Online (Sandbox Code Playgroud)