带有 Apache 2.4 的 RFC 2616

Col*_*inM 6 http reverse-proxy etags apache-2.4

我使用 Apache 2.4.3 作为反向代理,因为它宣传符合 RFC 2616。我的应用程序使用这样的标头来启用代理缓存:

Cache-Control: public, s-maxage=0
Expires: ... (+1 day)
X-Group: A
Vary: X-Group
ETag: W/"foo1"
Run Code Online (Sandbox Code Playgroud)

在第一个请求预热缓存后,如果我的应用程序更改为响应:

Cache-Control: public, s-maxage=0
Expires: ... (+1 day)
X-Group: B
Vary: X-Group
ETag: W/"foo2"
Run Code Online (Sandbox Code Playgroud)

如果来自 Apache 的 If-None-Match 标头与源生成的 ETag 匹配,则应用程序将响应 304 Not Modified。但是,Apache 然后缓存第二个 200 响应并新响应替换“foo1”记录,而不是缓存具有不同 ETag 的两个响应。因此,而不是If-None-Match: W/"foo1", W/"foo2"下一个重新验证请求只是If-None-Match: W/"foo2". 所以缓存不断地丢失而不是总是得到命中。

来自 RFC 2616 第 12.1 节:

然而,源服务器不限于这些维度,可以根据请求的任何方面改变响应,包括请求头字段之外的信息或本规范未定义的扩展头字段内的信息。

我为 Vary 尝试了以下组合:

Vary: X-Foo
Vary: *
Vary: User-Agent
Run Code Online (Sandbox Code Playgroud)

我还尝试了强和弱 ETag,无论我无法让 Apache 同时缓存两个响应,它总是比前一个更省钱。如果它不能保存一个页面的多个变体,那么 ETag 就没用了,Last-Modified 也一样好。

来自 Apache 2.4 文档:

mod_cache 实现了符合 RFC 2616 的 HTTP 内容缓存过滤器,支持缓存包含 Vary 标头的内容协商响应。

请注意,它表示“响应”复数。我是否误解了 HTTP 规范,还是 Apache 2.4 根本不完全支持 ETag?

Vor*_*ura 1

您举了几个这样的例子:

Cache-Control: public, s-maxage=0
Expires: ... (+1 day)
X-Group: A
Vary: X-Group
ETag: W/"foo1"
Run Code Online (Sandbox Code Playgroud)

我特别注意到Vary: X-Group标题。是X-Group请求头还是响应头?

根据RFC 2616 第 14.44 节Vary应列出将导致与源服务器不同的内容表示的任何请求标头。从您的示例中,我怀疑X-Group可能是响应标头,在这种情况下 mod_cache 将不会存储给定资源的多个版本。

您可以尝试的一件事是设置Vary: If-None-Match,这将使 mod_cache 为每个 ETag 存储资源的版本。诚然,我还没有尝试过这个。假设它有效,一个缺点是来自任何客户端的第一个请求都将是缓存未命中。