我遇到了Varnish ESI(Edge Side Includes)的问题:有时使用ESI的部分显示奇怪的字符,如下图所示:
我该如何解决这个问题?有趣的是,有时会出现这个问题,但有时候不会。
答案 0 :(得分:3)
这看起来像一个在Varnish中使用gzip的奇怪bug。如果你通过ESI获得gzipped block并且它不在缓存(MISS)中,你就会得到这个奇怪的符号。如果从缓存中获取此块,一切正常。解决方案是禁用内部路由的gzip:
if (req.url ~ "/_internal") {
# Telling ESI that we do not support gzip
remove req.http.Accept-Encoding;
.....
答案 1 :(得分:0)
看起来你的双重压缩ESI内容
答案 2 :(得分:0)
This chapter解释了在ESI处理过程中Varn如何使用gzip。我真的很喜欢这句话:
理论上,并且希望在实践中,您在上面阅读的所有内容也应该在您启用ESI时应用,否则它应该是您应该报告的错误。
长话短说,Varnish如何工作:在第一次请求页面(缓存未命中)时,Varnish直接从Web服务器呈现页面。之后 - 页面被放入缓存存储器,因此对于下一个请求,它将从存储器加载(缓存命中)。
不知何故,在第一次请求页面呈现解压缩时,会被置于存储 gzipped 中。这是发生错误的地方。由于nginx总是尝试gzip内容,我们在ungzip页面中使用了gzip include(在ESI期间)。
在上述文档章节中解释了这种行为:
在查找过程中,我们忽略任何"接受编码"在对象中变化:字符串,为了避免使用gzip和gunzip对象版本的对象,清漆可以根据需要进行gunzip。 (我们在查找时实现了这一点魔力,因此存储在持久存储中的任何对象都可以在启用或不启用gzip支持的情况下使用。)
所以,这个问题可以解决"带有一种尖峰 - 通过强制Varnish在ESI处理过程中始终发送未经压缩的内容(正如one of the answers 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);
}
# ...
}