gpt4 book ai didi

nginx 缓存但使用 `Cache-Control: public, s-maxage=0` 立即过期/重新验证

转载 作者:行者123 更新时间:2023-12-04 15:31:16 29 4
gpt4 key购买 nike

我想使用 HTTP 代理(例如 nginx)来缓存大型/昂贵的请求。这些资源对于任何授权用户都是相同的,但是后端需要在每个请求上检查它们的身份验证/授权。

听起来像 Cache-Control: public, max-age=0连同 nginx 指令 proxy_cache_revalidate on;是这样做的方法。代理可以缓存请求,但是每个后续请求都需要对后端进行条件 GET 以确保在返回缓存的资源之前它已获得授权。然后,如果用户未授权,则后端发送 403,如果用户被授权并且缓存的资源不是陈旧的,则发送 304,或者如果新资源已过期,则发送 200。

在 nginx 中如果 max-age=0设置请求根本不缓存。如果 max-age=1设置然后如果我在初始请求后等待 1 秒,那么 nginx 确实执行了条件 GET 请求,但是在 1 秒之前它直接从缓存中提供它,这对于需要验证的资源来说显然是非常糟糕的。

有没有办法让 nginx 缓存请求但立即需要重新验证?

请注意,这在 Apache 中确实可以正常工作。以下是 nginx 和 Apache 的示例,前 2 个 max-age=5,最后 2 个 max-age=0:

# Apache with `Cache-Control: public, max-age=5`

$ while true; do curl -v http://localhost:4001/ >/dev/null 2>&1 | grep X-Cache; sleep 1; done
< X-Cache: MISS from 172.x.x.x
< X-Cache: HIT from 172.x.x.x
< X-Cache: HIT from 172.x.x.x
< X-Cache: HIT from 172.x.x.x
< X-Cache: HIT from 172.x.x.x
< X-Cache: REVALIDATE from 172.x.x.x
< X-Cache: HIT from 172.x.x.x

# nginx with `Cache-Control: public, max-age=5`

$ while true; do curl -v http://localhost:4000/ >/dev/null 2>&1 | grep X-Cache; sleep 1; done
< X-Cached: MISS
< X-Cached: HIT
< X-Cached: HIT
< X-Cached: HIT
< X-Cached: HIT
< X-Cached: HIT
< X-Cached: REVALIDATED
< X-Cached: HIT
< X-Cached: HIT

# Apache with `Cache-Control: public, max-age=0`
# THIS IS WHAT I WANT

$ while true; do curl -v http://localhost:4001/ >/dev/null 2>&1 | grep X-Cache; sleep 1; done
< X-Cache: MISS from 172.x.x.x
< X-Cache: REVALIDATE from 172.x.x.x
< X-Cache: REVALIDATE from 172.x.x.x
< X-Cache: REVALIDATE from 172.x.x.x
< X-Cache: REVALIDATE from 172.x.x.x
< X-Cache: REVALIDATE from 172.x.x.x

# nginx with `Cache-Control: public, max-age=0`

$ while true; do curl -v http://localhost:4000/ >/dev/null 2>&1 | grep X-Cache; sleep 1; done
< X-Cached: MISS
< X-Cached: MISS
< X-Cached: MISS
< X-Cached: MISS
< X-Cached: MISS
< X-Cached: MISS

正如您在前两个示例中看到的,请求能够被 Apache 和 nginx 缓存,并且 Apache 甚至可以正确缓存 max-age=0 请求,但 nginx 不会。

最佳答案

我想解决自从我最初回答简单地使用 X-Accel-Redirect 以来在对话过程中出现的其他问题/疑虑。 (并且,如果需要 Apache 兼容性,则分别为 X-Sendfile)。

您寻求的“最佳”解决方案(没有 X-Accel-Redirect )是不正确的,原因不止一个:

  • 只需来自未经身份验证的用户的请求,即可清除您的缓存。
  • 如果所有其他请求都来自未经身份验证的用户,那么您实际上根本没有任何缓存。
  • 任何人都可以向资源的公共(public) URL 发出请求,以随时清除缓存。
  • 如果提供的文件实际上是静态的,那么您将浪费额外的内存、时间、磁盘和虚拟机/缓存空间来保存每个文件的多个副本。
  • 如果提供的内容是动态的:
  • 执行身份验证与资源生成的成本相同吗?那么当总是需要重新验证时,通过缓存它实际上可以获得什么?小于 2 倍的常数因子?您最好不要仅仅为了勾选复选标记而费心缓存,因为现实世界的改进将是微不足道的。
  • 生成 View 是否比执行身份验证更昂贵?缓存 View ,然后在高峰时间为数万个请求提供服务,这听起来是个好主意!但要成功实现这一点,您最好不要有任何未经身份验证的用户潜伏(因为即使是一对夫妇也可能导致必须重新生成 View 的重大且不可预测的费用)。
  • 在各种极端情况下缓存会发生什么?如果用户被拒绝访问,而开发人员没有使用适当的代码,然后被缓存怎么办?如果下一位管理员决定调整一两个设置,例如 proxy_cache_use_stale ,该怎么办? ?突然,您有未经身份验证的用户接收隐私信息。通过不必要地将应用程序的独立部分连接在一起,您将留下各种缓存中毒攻击向量。
  • 我认为返回 Cache-Control: public, max-age=0 在技术上不正确对于需要身份验证的页面。我相信正确的回答可能是 must-revalidateprivate代替public .

  • nginx“缺陷”缺乏对立即重新验证的支持 w/ max-age=0是设计使然(类似于它缺乏对 .htaccess 的支持)。
    根据以上几点,立即要求重新验证给定资源几乎没有意义,而且这只是一种无法扩展的方法,尤其是当您每秒必须满足“荒谬”数量的请求时使用最少的资源,并且没有不确定的条件。
    如果您需要一个由“委员会”设计的 Web 服务器,并且对每个厨房水槽应用程序和任何 RFC 的每个有问题的部分都具有向后兼容性,那么 nginx 根本不是正确的解决方案。

    另一方面, X-Accel-Redirect真的很简单,万无一失,事实上的标准。它可以让您以一种非常简洁的方式将内容与访问控制分开。这很简单。它实际上确保您的内容将被缓存,而不是您的缓存被彻底清除。这是值得追求的正确解决方案。试图在窥视时间内避免每 10K 份的“额外”请求,代价是在首先不需要缓存时只有“一个”请求,而当 10K 请求到来时实际上没有缓存,不是设计可扩展架构的正确方法。

    关于nginx 缓存但使用 `Cache-Control: public, s-maxage=0` 立即过期/重新验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41252208/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com