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:

The part with ESI sometimes displays strange characters

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. If you get gzipped block trough ESI and it is not in cache (MISS) you get this strange symbols. If you get this block from cache everything is ok. The solution is to disable gzip for internal routes:

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

.....

其他提示

Looks like your have double compressed ESI content

This chapter explains how Varnish works with gzip during ESI processing. 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.

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. 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. 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.

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. (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.)

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):

# 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归因
不隶属于 StackOverflow
scroll top