6. 边缘包含的内容组合

Varnish 可以通过将不同的页面(称为片段)组合成一个页面来创建网页。这些片段可以有各自的缓存策略。如果您的网站上有一个列表,显示网站上最受欢迎的五篇文章,那么这个列表就可以作为一个片段缓存,并包含在所有其他页面中。

如果使用得当,这一策略可以显著提高命中率,减少服务器的负荷。

在 Varnish 中,我们只实现了 ESI 的一小部分,因为其余大部分 ESI 规范设施都可以通过 VCL 更简单、更好地完成:

esi:include
esi:remove
<!--esi ...-->

未实现基于变量和 cookie 的内容替换。

Varnish 不会处理 HTML 注释中的 ESI 指令。

6.1 示例:esi:include

让我们来看一个如何使用的示例。这个简单的 cgi 脚本输出日期:

#!/bin/sh

echo 'Content-type: text/html'
echo ''
date "+%Y-%m-%d %H:%M"

现在,让我们来看一个包含 ESI 包含语句的 HTML 文件:

<HTML>
<BODY>
The time is: <esi:include src="/cgi-bin/date.cgi"/>
at this very moment.
</BODY>
</HTML>

要使 ESI 正常工作,您需要在 VCL 中激活 ESI 处理,就像这样:

sub vcl_backend_response {
    if (bereq.url == "/test.html") {
       set beresp.do_esi = true; // Do ESI processing
       set beresp.ttl = 24 h;    // Sets the TTL on the HTML above
    } elseif (bereq.url == "/cgi-bin/date.cgi") {
       set beresp.ttl = 1m;      // Sets a one minute TTL on
                                 // the included object
    }
}

请注意,对于包含的片段,除非也包含 <ESI::include …/> 指令,否则不需要设置 beresp.do_esi = true; 也应避免这样做。

6.2 示例:esi:remove 和 <!–esi … –>

esi:remove和<!-esi …->结构可用于在ESI可用与否的情况下呈现适当的内容,例如,您可以在ESI可用时包含内容,或在ESI不可用时链接到内容。在处理页面时,ESI 处理器会移除起始(“<!-esi”)和结束(“->”),但仍会处理内容。如果页面未被处理,它将保持不变,成为 HTML/XML 注释标记。ESI 处理器会移除 esi:remove 标记和其中包含的所有内容,这样就可以只在不对页面进行 ESI 处理时呈现内容。例如:

<esi:remove>
  <a href="http://www.example.com/LICENSE">The license</a>
</esi:remove>
<!--esi
<p>The full text of the license:</p>
<esi:include src="http://example.com/LICENSE" />
-->

6.3 失败时会发生什么?

默认情况下,片段必须有resp.status200 或 206,否则包含它们将导致父请求中止。

同样,如果片段是流式获取,且获取失败,父请求也会中止。

如果包含合成片段,即在 vcl_backend_error{}或中创建的片段vcl_synth{},则必须 (be)resp.status在之前设置为 200return(deliver);我们说“中止”而不是“失败”,因为当 Varnish 开始插入片段时,HTTP 响应头早已发送完毕,并且不再可能将父请求更改为 5xx,所以唯一的resp.status方法表示有问题的信号是关闭连接。但是,可以<ESI:include…通过设置来允许个人在失败时继续:

param.set feature +esi_include_onerror

并标记这些具体内容包括:

<ESI:include src="…" οnerrοr="continue"/>

6.4 ESI 片段也可以使用 ESI-includes 吗?

是的,但是深度受max_esi_depth 参数限制,以防止无限递归。

6.5 对 JSON 和其他非 XML 内容执行 ESI

Varnish 会查看对象的第一个字节,如果它不是“<”,Varnish 会假设您并不是真的想让 ESI 处理它。您可以通过以下方式禁用此检查:

param.set feature +esi_disable_xml_check

6.6 忽略 ESI 对象中的 BOM

如果后端输出 Unicode 字节顺序标记作为响应的第一个字节,则“<”检查将失败,除非您设置:

param.set feature +esi_remove_bom

6.7 无效 XML 上的 ESI

ESI 解析器期望 XML 的格式相当良好,但如果您是包含非 XML 文件的 ESI,则这可能会失败。您可以通过设置使 ESI 解析器忽略除 ESI 标记之外的任何内容:

param.set feature +esi_ignore_other_elements

6.8 ESI 包含 HTTPS 协议

如果ESI:include标签指定了HTTPS协议,默认情况下它将被忽略,因为Varnish无法通过加密来获取它。如果您希望 Varnish 像执行其他操作一样获取它们,请设置:

param.set feature +esi_ignore_https

6.9 部分响应的 ESI (206)

Varnish 支持范围请求,但一般来说,部分响应在 ESI 上下文中没有意义。

如果您确实知道自己在做什么,请将 206 更改为 200:

sub vcl_backend_response {
    if (beresp.status == 206 && beresp.http.secret == "swordfish") {
        set beresp.do_esi = True;
        set beresp.status = 200;
    }
}

6.10 ESI 和返回(vcl(…))

如果原始客户端请求使用 return(vcl(...))in切换到不同的 VCL vcl_recv,则任何 esi:include-requests 仍将在与原始请求相同的 VCL 中开始,而不是 在它切换到的 VCL 中开始。

6.11 ESI 和 gzip 压缩

Varnish 的 ESI 实现会自动处理 gzip 压缩,无论它如何混合:父请求可以压缩或解压缩,片段也可以压缩或解压缩,这一切都可以解决。

Varnish 会分别压缩 ESI 响应的所有部分,并在交付过程中将它们动态拼接在一起,这会对压缩比产生负面影响。

当您使用 gzip 压缩响应时,它将在获取过程中被解压缩并部分重新压缩。set beresp.do_esi = True;

部分压缩减少了删除冗余的机会,因为 gzip 数据流中的反向引用不能指向它自己的部分之外。

另一种影响压缩率的情况是,如果将未压缩的片段插入到压缩的响应中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值