简体   繁体   English

清漆 ESI:奇怪的字符

[英]Varnish ESI: strange characters

I'm having a problem with Varnish ESI (Edge Side Includes): sometimes the part which uses ESI displays strange characters, like the ones of image below:我在使用 Varnish ESI(边缘包含)时遇到问题:有时使用 ESI 的部分会显示奇怪的字符,如下图所示:

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

How can I fix this?我怎样才能解决这个问题? The funny part is that sometimes this problem occurs, but sometimes not.有趣的是,有时会出现这个问题,但有时不会。

This looks like a strange bug with gzip in Varnish.这看起来像是 Varnish 中 gzip 的一个奇怪错误。 If you get gzipped block trough ESI and it is not in cache (MISS) you get this strange symbols.如果您通过 ESI 获得 gzipped 块并且它不在缓存中(MISS),您会得到这个奇怪的符号。 If you get this block from cache everything is ok.如果您从缓存中获取此块,则一切正常。 The solution is to disable gzip for internal routes:解决方案是为内部路由禁用 gzip:

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

..... .....

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

This chapter explains how Varnish works with gzip during ESI processing. 本章解释了 Varnish 在 ESI 处理过程中如何与 gzip 一起工作。 I really like this sentence:我真的很喜欢这句话:

In theory, and hopefully in practice, all you read above should apply also when you enable ESI, if not it is a bug you should report.理论上,希望在实践中,当您启用 ESI 时,您上面阅读的所有内容也应该适用,如果不是,则应该报告错误。

Telling the long story short, how Varnish works: during first request to the page (cache miss) a page is rendered by Varnish directly from web-server.长话短说,Varnish 是如何工作的:在对页面的第一次请求(缓存未命中)期间,页面由 Varnish 直接从 Web 服务器呈现。 And after that - page is put into cache storage, so for next request it will be loaded from storage (cache hit).之后 - 页面被放入缓存存储,因此对于下一个请求,它将从存储加载(缓存命中)。

Somehow, during first request page is rendered ungzipped , but is placed into storage gzipped .不知何故,在第一个请求页面呈现为ungzipped ,但被放入存储gzipped And it was the place where bug occured.这就是发生错误的地方。 Since nginx always tries to gzip content, we had gzipped include (during ESI) in the ungzipped page.由于 nginx 总是尝试 gzip 内容,我们在未压缩的页面中 gzipped 包含(在 ESI 期间)。

This behaviour is explained in the mentioned documentation chapter:提到的文档章节中解释了此行为:

During lookup, we ignore any "Accept-encoding" in objects Vary: strings, to avoid having a gzip and gunzip'ed version of the object, varnish can gunzip on demand.在查找过程中,我们忽略对象 Vary: 字符串中的任何“接受编码”,为了避免对象的 gzip 和 gunzip 版本,varnish 可以按需进行 gunzip。 (We implement this bit of magic at lookup time, so that any objects stored in persistent storage can be used with or without gzip support enabled.) (我们在查找时实现了这一点魔术,以便在启用或不启用 gzip 支持的情况下都可以使用存储在持久存储中的任何对象。)

So, this problem can be "solved" with a sort of spike - by forcing Varnish to always send ungzipped content during ESI processing (as it is mentioned in one of the answers by klipach ):因此,这个问题可以通过一种尖峰来“解决” - 通过强制 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);
    }
    # ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM