ADC

配置 cookie、标头和轮询

本主题介绍如何配置缓存管理 Cookie、HTTP 标头和源服务器轮询。这包括修改导致缓存偏离文档标准的默认行为、覆盖可能导致可缓存内容未存储在缓存中的 HTTP 标头,以及将缓存配置为始终轮询源以获取更新的内容。

缓存行为与标准的分歧

默认情况下,集成缓存遵循以下 RFC 标准:

  • RFC 2616,“HTTP HTTP/1.1”
  • RFC 2617“HTTP 身份验证:基本和摘要访问身份验证”中描述的缓存行为
  • RFC 2965“HTTP 状态管理机制”中描述的缓存行为

内置策略和默认内容组属性可确保符合大多数这些标准。

默认的集成缓存行为与规范有所不同,如下所示:

  • 对 Vary 标题的支持有限。默认情况下,任何包含 Vary 标头的响应都被视为不可缓存,除非它被压缩。压缩的响应包含内容编码:gzip、内容编码:deflate 或内容编码:pack200-gzip,即使它包含 Vary: Accept 编码标头,也可以缓存。
  • 集成缓存会忽略标头缓存控制的值:无缓存和缓存控制:private。例如,包含缓存控制:no-cache= “Set-Cookie”的响应被视为响应包含缓存控制:无缓存。默认情况下,不会缓存响应。
  • 图像(内容类型 = image/*)始终被视为可缓存,即使图像响应包含 set-cookie 或 set-cookie2 标头,或者图像请求包含 cookie 标头。集成缓存会在缓存响应之前从响应中删除 set cookie 和 set-cookie2 标头。这与 RFC 2965 有所不同。您可以按如下方式配置符合 RFC 的行为:
add cache policy rfc_compliant_images_policy -rule "http.res.header.set-cookie2.exists || http.res.header.set-cookie.exists" -action NOCACHE


bind cache global rfc_compliant_images_policy -priority 100 -type REQ_OVERRIDE
<!--NeedCopy-->
  • 请求中的以下缓存控制标头强制兼容 RFC 的缓存从源服务器重新加载缓存的响应:

Cache-control: max-age=0

Cache-control: no-cache

为防范拒绝服务攻击,此行为不是默认行为。

  • 默认情况下,缓存模块认为响应是可缓存的,除非另有响应头状态。要使此行为符合 RFC 2616 标准,请 -weakNegResExpiry 将所有内容组的 -weakPosRelExpiry 和设置为 0。

Cookie 通常针对用户进行个性化设置,通常不应缓存。 Remove Response Cookies 参数在缓存响应之前删除 Set-Cookie and Set-Cookie2 标头。默认情况下,内容组的 Remove Response Cookies 选项会阻止缓存带有 Set-CookieSet-Cookie2 标头的响应。

注意: 缓存图像时,内置行为是在缓存之前删除 Set-CookieSet-Cookie2 标头,无论内容组的配置方式如何。

Citrix 建议您接受存储嵌入式响应(例如图像)的每个内容组的默认值 Remove Response Cookies

要使用命令行界面为内容组配置 Remove Response Cookies,请执行以下操作:

在命令提示符下,键入:

set cache contentgroup <name> -removeCookies YES

  1. 导航到“优化”>“集成缓存”>“内容组”,然后选择内容组。
  2. 其他 选项卡的 设置 组中,选择删除响应 Cookie 选项。

在响应时插入 HTTP 标头

集成缓存可以在缓存请求产生的响应中插入 HTTP 标头。NetScaler 设备不会更改因缓存丢失而导致的响应中的标头。

下表介绍了可以在响应中插入的标头。

标头 规范
年龄 提供响应的持续时间(以秒为单位),从源服务器上生成响应的时间计算得出。默认情况下,缓存会为从缓存提供的每个响应插入一个年龄标头。
通过 列出请求或响应的起点和终点之间的协议和收件人。NetScaler 设备在其从缓存中提供的每个响应中插入一个 Via 标头。插入的标头的默认值为 NS-CACHE-10.0:NetScaler IP 地址的最后一个八位字节。” 有关详细信息,请参阅“为缓存配置全局属性”。“
Tag 缓存支持使用上次修改和 Tag 标头进行响应验证,以确定响应是否过时。仅当缓存响应而源服务器尚未插入自己的 Tag 标头时,缓存才会在响应中插入 TagTag 值是任意的唯一数字。如果从源服务器刷新响应,则响应的 Tag 值会发生变化,但是如果服务器发送 304(未更新对象)响应,它将保持不变。源服务器通常不会为动态内容生成验证器,因为动态内容被认为是不可缓存的。您可以覆盖此行为。插入 Tag 标头时,允许缓存无法提供完整的响应。相反,用户代理需要首次缓存集成缓存发送的动态响应。要强制用户代理缓存响应,您可以将集成缓存配置为插入 Tag 标头并替换原始提供的 Cache-Control 标头。
Cache-Control NetScaler 设备通常不会修改源服务器提供的响应中的缓存标头。如果源服务器发送的响应被标记为不可缓存,则即使 NetScaler 设备缓存了响应,客户端也会将该响应视为不可缓存。要在用户代理中缓存动态响应,可以替换源服务器中的 Cache-Control 标头。这仅适用于用户代理和其他中间缓存。它们不会影响集成缓存。
标头 规范
年龄 提供响应的持续时间(以秒为单位),从源服务器上生成响应的时间计算得出。默认情况下,缓存会为从缓存提供的每个响应插入一个年龄标头。
通过 列出请求或响应的起点和终点之间的协议和收件人。NetScaler 设备在其从缓存中提供的每个响应中插入一个 Via 标头。插入的标头的默认值为“NS-CACHE-9.2:NetScaler IP 地址的最后一个八位组”。有关详细信息,请参阅“为缓存配置全局属性”。“
Tag 缓存支持使用“上次修改时间”和“标签”标头进行响应验证,以确定响应是否过时。仅当缓存响应而源服务器尚未插入自己的 Tag 标头时,缓存才会在响应中插入 TagTag 值是任意的唯一数字。如果从源服务器刷新响应,则响应的 Tag 值会发生变化,但是如果服务器发送 304(未更新对象)响应,它将保持不变。源服务器通常不会为动态内容生成验证器,因为动态内容被认为是不可缓存的。您可以覆盖此行为。插入 Tag 标头时,允许缓存无法提供完整的响应。相反,用户代理需要首次缓存集成缓存发送的动态响应。要强制用户代理缓存响应,您可以将集成缓存配置为插入 Tag 标头并替换原始提供的 Cache-Control 标头。
Cache-Control NetScaler 设备通常不会修改源服务器提供的响应中的缓存标头。如果源服务器发送的响应被标记为不可缓存,则即使 NetScaler 设备缓存了响应,客户端也会将该响应视为不可缓存。要在用户代理中缓存动态响应,可以替换源服务器中的 Cache-Control 标头。这仅适用于用户代理和其他中间缓存。它们不会影响集成缓存。

插入年龄、通过或标签标题

以下过程描述了如何插入年龄、Via 和 ETag 标头。

使用 NetScaler 命令界面插入 Age、Via 或 Etag 标头:

在命令提示符下,键入:

set cache contentgroup <name> -insertVia YES -insertAge YES -insertETag YES

使用 NetScaler GUI 配置 Age、Via 或 Etag 标头

  1. 导航到“优化”>“集成缓存”>“内容组”, 然后选择 内容组
  2. 在“其他”选项卡的“HTTP 标头插入”组中,根据需要选择“通过”、“年龄”或“ETag”选项。
  3. 其他标题类型的值是自动计算的。您可以在缓存的主要设置中配置 Via 值。

插入缓存控制标头

当集成缓存替换源服务器插入的 Cache-Control 标头时,它也会替换 Expires 标头。新的 Expires 标头包含过去的到期时间。这样可以确保 HTTP/1.0 客户端和缓存(不能理解 Cache-Control 标头)不会缓存内容。

使用 NetScaler 命令界面插入缓存控制标头

在命令提示符下,键入:

set cache contentgroup <name> -cacheControl <value>

使用 NetScaler GUI 插入缓存控制标头

  1. 导航到 优化 > 集成缓存 > 内容组,然后
    1. 单击 到期方法 选项卡,清除启发式和默认到期设置,然后在过期后内容文本框中设置相关值。
    2. 单击 其他 选项卡,然后在缓存控制文本框中键入要插入的标题。或者,单击配置以在缓存的响应中设置 Cache-Control 指令。

忽略请求中的缓存控制和编译指示标头

默认情况下,缓存模块处理缓存控制和 Pragma 标头。缓存控制标头中的以下令牌按照 RFC 2616 中的说明进行处理。

  • 最大年龄
  • max-stale
  • 只有在缓存的情形下
  • 没有缓存

Pragma:请求中的无缓存标头的处理方式与缓存控制:无缓存标头的处理方式相同。

如果您将缓存模块配置为忽略 Cache-Control 和 Pragma 标头,则包含 Cache-Control: No-Cache 标头的请求会导致 NetScaler 设备从原始服务器检索响应,但缓存的响应不会更新。如果缓存模块处理 Cache-Control 和 Pragma 标头,则会刷新缓存的响应。

下表总结了这些标头的各种设置以及忽略浏览器的重新加载请求设置的含义。

忽略缓存控件和 Pragma 标头的设置 忽略浏览器的重新加载请求的设置 结果
是或否 忽略来自客户端的缓存控制和 Pragma 标头,包括缓存控制:no-cache 指令。
Cache-Control:无缓存标头会产生缓存未命中,但不刷新已存在于缓存中的响应。
包含 Cache-Control: no-cache 标头的请求会导致缓存未命中并刷新存储的响应。

使用命令行界面忽略请求中的缓存控制和 Pragma 标头

在命令提示符下,键入:

set cache contentgroup <name> -ignoreReqCachingHdrs YES

使用命令行界面忽略浏览器重新加载请求

在命令提示符下,键入:

set cache contentgroup <name> -ignoreReloadReq NO

注意: 默认情况下,-ignoreLoadreQ 参数设置为是。

使用 GUI 忽略请求中的缓存控件和 Pragma 标头

  1. 导航到“优化”>“集成缓存”>“内容组”,然后选择内容组。
  2. 其他 选项卡的 设置 组中,选择 请求 选项中 的忽略缓存控件和 Pragma 标头

忽略缓存控制标头的策略示例:

在以下示例中,您可以配置请求时覆盖策略来缓存包含 Content-type: image/* 的响应,而不管响应中的 Cache-Control 标头如何。

配置请求时覆盖策略以缓存带有 image/* 的所有响应

使用“全部失效”选项刷新缓存。

配置新的缓存策略,然后将该策略定向到特定的内容组。更多信息请参阅“在集成缓存中配置策略”。“

确保将策略使用的内容组配置为忽略 Cache-Control 标头,如在请求中忽略缓存控制和 Pragma 标头中所述。“

将策略绑定到请求时间覆盖策略库。

有关更多信息,请参阅 全局绑定集成缓存策略 主题。

每次收到请求时轮询源服务器

您可以将 NetScaler 设备配置为在提供存储的响应之前始终咨询原始服务器。这就是所谓的每次轮询(PET)。当 NetScaler 设备咨询原始服务器且 PET 响应未过期时,来自源服务器的完整响应不会覆盖缓存的内容。在提供客户端特定内容时,此属性非常有用。

PET 响应到期后,当源服务器收到第一个完整响应时,NetScaler 设备会刷新该响应。

每次轮询 (PET) 函数的工作原理如下:

对于具有标签或上次修改标头形式的验证器的缓存响应,如果响应过期,它将自动标记为 PET 并进行缓存。

您可以为内容组配置 PET。

如果将内容组配置为 PET,则内容组中的每个响应都将标记为 PET。PET 内容组可以存储没有验证器的响应。自动标记为 PET 的响应始终过期。根据您配置内容组的方式,属于宠物内容组的响应可能会在延迟后过期。

轮询会影响两种类型的请求:

  • 有条件的请求:客户端发出条件请求,以确保其拥有的响应是最新的副本。用户代理对缓存的 PET 响应的请求始终会转换为条件请求并发送到源服务器。条件请求在 If-Modified-SinceIf-None-Match 标头中有验证器。标 If-Modified-Since 题包含标题中的 Last-Modified 时间。如果无匹配标题包含响应的标签标题值。如果客户端的响应副本是新的,则源服务器将以 304“未修改”进行回复。如果副本过时,条件响应会生成包含整个响应的 200 OK。
  • 非条件请求:无条件请求只能生成包含整个响应的 200 OK。
源服务器响应 操作
发送完整的回复 源服务器按原样将响应发送给客户端。如果缓存的响应已过期,则会刷新它。
304 未修改 304 响应中的以下标头值与缓存的响应合并,缓存的响应将提供给客户端:日期、过期、年龄、缓存控制标头 Max-Age 和 S-Maxage 令牌
401 未经授权;400 错误请求;405 方法不允许;406 不可接受;需要 407 代理身份验证 源的响应按原样提供给客户端。缓存的响应没有改变。
任何其他错误响应,例如 404 未找到 源的响应按原样提供给客户端。缓存的响应将被删除。

注意: “每次轮询”参数将受影响的响应视为不可存储的响应。

每次使用命令行界面配置轮询

在命令提示符下,键入:

add cache contentgroup <contentGroupName> -pollEveryTime YES

使用 GUI 进行轮询

  1. 导航到“优化”>“集成缓存”>“内容组”,然后选择内容组。
  2. 在“其他”选项卡的“设置”组中,选择“每次轮询(使用每个请求的来源验证缓存内容)”选项。

PET 和客户特定的内容

PET 功能可以确保为客户定制内容。例如,以多种语言提供内容的网站会检查 Accept-Language 请求标头,以便为其提供的内容选择语言。对于以英语为主导语言的多语言网站,所有英语内容都可以缓存在 PET 内容组中。这样可以确保每个请求都会发送到源服务器,以确定响应的语言。如果响应是英语且内容没有更改,则源服务器可以向缓存提供 304 Nnot Codified。

以下示例显示了以下命令:在 PET 内容组中缓存英语响应、配置在缓存中标识英语响应的命名表达式,以及配置使用此内容组和命名表达式的策略。粗体用于强调:

add cache contentgroup EnglishLanguageGroup -pollEveryTime YES
add expression containsENExpression –rule "http.res.header(\\"Content-Language\\").contains(\\"en\\")"
add cache policy englishPolicy -rule containsENExpression -action CACHE -storeInGroup englishLanguageGroup
bind cache policy englishPolicy -priority 100 -precedeDefRules NO
<!--NeedCopy-->

PET 和身份验证、授权和审计

Outlook Web 访问 (OWA) 是一个很好的例子,动态生成的内容从 PET 中受益。所有邮件回复(*.EML 对象)都有一个 ETag 验证器,可以将它们存储为 PET 响应。

每个邮件响应请求都会传递到源服务器,即使响应已缓存也是如此。源服务器决定请求者是否经过身份验证和授权。它还会验证响应是否存在于源服务器中。如果所有结果均为肯定,则源服务器将发送 304 未修改响应。