我正在考虑问Software Recommendations,但后来我发现这可能是一个太奇怪的请求,需要先澄清一下。
我的观点是:
etag
expires
和max-age
标题在这里无效。)基本上,代理应包含将etag
映射到响应内容的缓存。从服务器获取etag
,在最常见的情况下,服务器根本不处理响应内容。
它应如下所示:代理总是向服务器发送请求然后
etag
,代理根据它进行查找
etag
,etag
的回复,
为简单起见,我省略了if-none-match
标题的处理,这很明显。
我的理由是最常见的情况1.1可以在服务器中非常有效地实现(使用它的缓存映射请求到etags
;内容没有缓存在服务器中),所以在没有服务器处理响应内容的情况下,可以处理大多数请求。这应该比首先从侧缓存获取内容然后提供内容更好。
在案例1.2中,有两个对服务器的请求,这听起来很糟糕,但并不比服务器要求侧缓存和错过更糟糕。
Q1:我想知道如何将第一个请求映射到HTTP。在案例1中,它就像一个HEAD请求。在案例2中,它就像GET一样。两者之间的决定取决于服务器:如果它可以在不计算内容的情况下为etag
提供服务,那么它就是案例1,否则就是案例2。
Q2:是否有反向代理做这样的事情?我读过有关nginx,HAProxy和Varnish的内容,但事实并非如此。这导致我 Q3:这是个坏主意吗?为什么呢?
问题4:如果没有,那么哪个现有代理最容易适应?
来自用户/catalog/123/item/456
的{{1}}等GET请求已提供了一些内容U1
和C1
。代理将etag: 777777
存储在密钥C1
下。
现在,同一请求来自用户777777
。代理转发它,服务器返回U2
并且代理很幸运,在其缓存中找到etag: 777777
(大小写 1.1 )并将其发送到C1
。 在此示例中,不是代理的客户端都不知道预期的结果。
有趣的是,服务器如何在不计算答案的情况下知道U2
。例如,它可以有一条规则,声明此表单的请求为所有用户返回相同的结果,假设允许给定用户查看它。因此,当etag
发出请求时,它会计算U1
并将C1
存储在密钥etag
下。当同一请求来自/catalog/123/item/456
时,它只是验证了允许U2
查看结果。
答案 0 :(得分:2)
Q1 :这是一个GET请求。服务器可以在没有正文的情况下回答“304未修改”。
Q2 :openresty(带有一些额外模块的nginx)可以做到,但您需要自己实现一些逻辑(请参阅下面的详细说明)。
Q3 :根据您提问中的信息,这听起来是个合理的想法。只是一些值得思考的东西:
您还可以将页面拆分为可以独立缓存的用户特定和通用部分。
您不应期望缓存永远保留计算的响应。因此,如果服务器返回304 not modified
etag: 777777
(根据您的示例),但缓存不知道它,您应该可以选择强制重新构建答案,例如:使用自定义标头X-Force-Recalculate: true
的其他请求。
不完全是您问题的一部分,但是:请务必设置正确的Vary
标头以防止出现缓存问题。
如果这只是关于权限,您也可以使用签名cookie中的权限信息。缓存可以在不询问服务器的情况下从cookie中获取权限,并且由于签名,cookie是防篡改的。
Q4 :我会使用openresty,特别是lua-resty-redis module。将缓存的内容放入以etag
为键的redis键值存储中。你需要在Lua中编写查找逻辑代码,但它不应该超过几行。