【问题标题】:Varnish: Make cache dependent on X-Forwarded-Proto httpsVarnish:使缓存依赖于 X-Forwarded-Proto https
【发布时间】:2014-01-11 21:14:48
【问题描述】:

以下情况: 服务器上有一个用于缓存的 apache 和 Varnish。 SSL 由亚马逊负载均衡器处理。 如果使用 https 请求页面,则 http 标头“X-Forwarded-Proto”设置为“https”。 页面有时不同(例如,使用安全连接时必须使用 https 获取链接/图像)

如果 X-Forwarded-Proto 标头不同,我如何告诉 varnish 页面不同? 就像现在一样,首先访问的内容都会被缓存并为 http 和 https 提供服务!

【问题讨论】:

    标签: http caching header varnish


    【解决方案1】:
    sub vcl_recv {
        if ( req.http.X-Forwarded-Proto !~ "(?i)https") {
            set req.http.x-Redir-Url = "http://" + ...req url;
        }else{
            set req.http.x-Redir-Url = "https://" + ...req url;
        }
    }
    

    抱歉,我现在更新了代码。我就是这个意思。

    【讨论】:

    • 谢谢,但我不想将所有用户重定向到 https!我只是想让varnish为http和https提供不同的页面,不一样!
    • 以上是出现在 Varnish Page 中的示例。但它会根据“X-Forwarded-Proto”向您展示在何处以及如何处理请求它需要在 if-else 中使用正确的值
    • 好的,但我不知道如何/是否可以告诉 varnish 缓存页面,但使用另一个键。我只是看看如何缓存它或不缓存它!
    • 不确定这是否是您需要的,但为了清楚起见,我现在更新了代码。我就是这个意思。
    【解决方案2】:

    我想你想要的是拥有相同 URI 的不同缓存版本,使用自定义 vcl_hash 很容易:

    sub vcl_hash {
      # ...
      if (req.http.X-Forwarded-Proto &&
          req.url !~ "(?i)\.(png|gif|jpeg|jpg|ico|gz|tgz|bz2|tbz|mp3|ogg|zip|rar|otf|ttf|eot|woff|svg|pdf)$") {
         hash_data(req.http.X-Forwarded-Proto);
      }
      # ...
    }
    

    在此示例中,静态文件仅缓存一次,其余的(html、js、css..)缓存在 2 个不同的版本中(假设 X-Forwarded-Proto 仅采用两个值)。

    您可以在https://github.com/NITEMAN/varnish-bites/blob/master/varnish3/drupal-base.vcl 上查看更广泛的示例

    【讨论】:

    • 非常感谢!效果很好!
    【解决方案3】:

    问题和答案已经很老了。

    到目前为止,最佳做法是使用 Vary 标头(具有讽刺意味的是,这个人建议谁在 2015 年删除了他的答案)。

    你应该尽可能避免hash_data()

    您的后端应该发送Vary: X-Forwarded-Proto,Accept-Encoding。 Varnish 服务器看到头部,并根据终止实例设置的头部中的协议创建单独的缓存条目。

    【讨论】:

    • 如果你能添加一个为什么应该避免 hash_data 的来源会很棒!
    • @YesBarry @Josef 使用hash_data() 并不“坏”,但是,来自后端的 URL 确实有变化的决定是由后端/应用程序做出的决定,而不是由 Varnish .网站是否有针对移动/桌面设备的变体,取决于网站项目,而不是 Varnish。 Vary 标头的目的是向下游实例发出变化信号。关注点分离!
    • @Josef 还有一件事:在外国公司运营的外国网络中,您无法直接编辑下游缓存实例的配置。同样,您使用Vary 标头告诉下游缓存构建特定主机+ url 组合的变体。
    • @Josef 对我来说,不在 varnish 中这样做不仅在语义上更好,而且因为 Vary 标头是通用的。它们无需配置即可工作,并且可以与所有代理一起使用,而不仅仅是与 Varnish 一起使用。想象一下,您停止使用 Varnish 并转而使用其他东西,所有这些缓存都可以正常工作,而无需学习和构建新配置。此外,当您想禁用提供 http 和 https 版本时,您只需停止发送 Vary 标头 - 无需在 varnish 中进行任何配置。
    • @DanFromGermany 感谢您的回复!我确实同意了你的回答,它解决了我的问题。但出于好奇,我最终在事后发表了评论。我可以建议您将其中一些添加到您的实际答案中吗?谢谢!
    猜你喜欢
    • 1970-01-01
    • 2013-01-04
    • 2014-06-14
    • 2019-01-26
    • 2016-11-11
    • 2016-03-30
    • 2015-04-09
    相关资源
    最近更新 更多