2

我在使用 Varnish ESI(Edge Side Includes)时遇到问题:有时使用 ESI 的部分会显示奇怪的字符,如下图所示:

带 ESI 的部分有时会显示奇怪的字符

我怎样才能解决这个问题?有趣的是,有时会出现这个问题,但有时不会。

4

3 回答 3

3

这看起来像是 Varnish 中 gzip 的一个奇怪错误。如果您通过 ESI 获得 gzipped 块并且它不在缓存中(MISS),您会得到这个奇怪的符号。如果您从缓存中获取此块,则一切正常。解决方案是为内部路由禁用 gzip:

if (req.url ~ "/_internal") {
    # Telling ESI that we do not support gzip
    remove req.http.Accept-Encoding;

......

于 2012-11-26T11:49:49.533 回答
0

看起来你有双重压缩 ESI 内容

于 2012-11-15T17:52:20.740 回答
0

本章解释了在 ESI 处理过程中 Varnish 如何与 gzip 一起工作。我真的很喜欢这句话:

理论上,并希望在实践中,当您启用 ESI 时,您在上面阅读的所有内容也应该适用,如果不是,您应该报告它是一个错误。

长话短说,Varnish 是如何工作的:在对页面的第一次请求(缓存未命中)期间,Varnish 直接从 Web 服务器呈现页面。之后 - 页面被放入缓存存储中,因此对于下一个请求,它将从存储中加载(缓存命中)。

不知何故,在第一个请求页面呈现ungzipped,但被放入存储gzipped。这就是bug发生的地方。由于 nginx 总是尝试对内容进行 gzip,因此我们在未压缩的页面中对包含(在 ESI 期间)进行了 gzip 压缩。

提到的文档章节中解释了此行为:

在查找过程中,我们忽略了对象 Vary: 字符串中的任何“接受编码”,为了避免对象的 gzip 和 gunzip 版本,varnish 可以按需进行 gunzip。(我们在查找时实现了这一点,因此存储在持久存储中的任何对象都可以在启用或不启用 gzip 支持的情况下使用。)

因此,这个问题可以通过一种尖峰来“解决”——通过强制 Varnish 在 ESI 处理期间始终发送未压缩的内容(正如klipach答案之一所述):

# www.vcl

sub vcl_recv {
    # ...
    if (req.url ~ "/_internal") {
        # Telling ESI that we do not support gzip
        remove req.http.Accept-Encoding;

        return(lookup);
    }
    # ...
}
于 2012-11-28T11:15:21.527 回答