

# 缓存和可用性
<a name="ConfiguringCaching"></a>

您可以使用 CloudFront 来减少原始服务器必须直接响应的请求数量。借助 CloudFront 缓存，更多对象可以从更靠近用户的 CloudFront 边缘站点提供。这既减少了源服务器上的负载，也减少了延迟。

CloudFront 可以通过边缘缓存提供服务的请求越多，CloudFront 为获取对象的最新版本或唯一版本而需转发到源的查看器请求就越少。要优化 CloudFront 以尽可能少地向您的源发出请求，请考虑使用 CloudFront Origin Shield。有关更多信息，请参阅 [使用 Amazon CloudFront Origin Shield](origin-shield.md)。

直接从 CloudFront 缓存提供服务的请求与所有请求相比的比例称为*缓存命中率*。您可在 CloudFront 控制台中查看命中、未命中和出错的查看器请求百分比。有关更多信息，请参阅 [查看 CloudFront 缓存统计报告](cache-statistics.md)。

很多因素都会影响缓存命中率。您可以按照[增加直接从 CloudFront 缓存提供服务的请求的比例（缓存命中率）](cache-hit-ratio.md)中的指导操作来调整您的 CloudFront 分配配置以提高缓存命中率。

要了解添加和删除您希望 CloudFront 提供的内容的信息，请参阅[添加、删除或替换 CloudFront 分配的内容](AddRemoveReplaceObjects.md)。

**Topics**
+ [

# 增加直接从 CloudFront 缓存提供服务的请求的比例（缓存命中率）
](cache-hit-ratio.md)
+ [

# 使用 Amazon CloudFront Origin Shield
](origin-shield.md)
+ [

# 通过 CloudFront 源失效转移来优化高可用性
](high_availability_origin_failover.md)
+ [

# 管理内容保留在缓存中的时间长度（过期）
](Expiration.md)
+ [

# 根据查询字符串参数缓存内容
](QueryStringParameters.md)
+ [

# 根据 Cookie 缓存内容
](Cookies.md)
+ [

# 根据请求标头缓存内容
](header-caching.md)

# 增加直接从 CloudFront 缓存提供服务的请求的比例（缓存命中率）
<a name="cache-hit-ratio"></a>

您可以通过增加直接从 CloudFront 缓存提供服务的查看器请求的比例（而不是转至源服务器以获得内容）来提高性能。这称为提高缓存命中率。

以下部分说明了如何提高缓存命中率。

**Topics**
+ [

## 指定 CloudFront 缓存对象的时间长度
](#cache-hit-ratio-duration)
+ [

## 使用源护盾
](#cache-hit-ratio-use-origin-shield)
+ [

## 根据查询字符串参数进行缓存
](#cache-hit-ratio-query-string-parameters)
+ [

## 根据 Cookie 值进行缓存
](#cache-hit-ratio-cookies)
+ [

## 根据请求标头进行缓存
](#cache-hit-ratio-request-headers)
+ [

## 不需要压缩时删除 `Accept-Encoding` 标头
](#cache-hit-ratio-remove-accept-encoding)
+ [

## 通过 HTTP 提供媒体内容
](#cache-hit-ratio-http-streaming)

## 指定 CloudFront 缓存对象的时间长度
<a name="cache-hit-ratio-duration"></a>

要提升缓存命中率，您可以配置源来将 [Cache-Control max-age](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control) 指令添加到您的对象，并为 `max-age` 指定在实践中可行的最长值。缓存持续时间越短，CloudFront 将请求发送到源（用以确定对象是否已更改，并获取最新版本）的次数就越多。您可以用 `stale-while-revalidate` 和 `stale-if-error` 指令来补充 `max-age`，以进一步提高某些条件下的缓存命中率。有关更多信息，请参阅 [管理内容保留在缓存中的时间长度（过期）](Expiration.md)。

## 使用源护盾
<a name="cache-hit-ratio-use-origin-shield"></a>

Origin Shield 可以帮助提高 CloudFront 分配的缓存命中率，因为它在源之前提供了额外的缓存层。当您使用 Origin Shield 时，从所有 CloudFront 缓存层到您的源的所有请求都来自一个位置。CloudFront 可以使用来自 Origin Shield 的单个源请求检索每个对象，CloudFront 缓存的所有其他层（边缘站点和[区域边缘缓存](HowCloudFrontWorks.md#CloudFrontRegionaledgecaches)）可以从 Origin Shield 中检索对象。

有关更多信息，请参阅 [使用 Amazon CloudFront Origin Shield](origin-shield.md)。

## 根据查询字符串参数进行缓存
<a name="cache-hit-ratio-query-string-parameters"></a>

如果您将 CloudFront 配置为基于查询字符串参数进行缓存，则可以通过以下方法来改进缓存：
+ 将 CloudFront 配置为仅转发您的源将返回唯一对象的那些查询字符串参数。
+ 为相同参数的所有实例使用相同的大小写。例如，如果一个请求包含 `parameter1=A`，另一个请求包含 `parameter1=a`，则 CloudFront 在一个请求包含 `parameter1=A` 而一个请求包含 `parameter1=a` 时，会将两个请求分别转发到源。然后，CloudFront 分别缓存源返回的对应对象，即使这些对象完全相同。如果您仅使用 `A` 或 `a`，CloudFront 会将较少的请求转发到源。
+ 按相同的顺序列出参数。与大小写不同的情况相似，如果对象的一个请求包含查询字符串 `parameter1=a&parameter2=b`，而相同对象的另一个请求包含 `parameter2=b&parameter1=a`，CloudFront 会将两个请求转发到源，并分别缓存对应的对象，即使它们完全相同。如果您始终为参数使用相同的顺序，CloudFront 会将较少的请求转发到源。

有关更多信息，请参阅 [根据查询字符串参数缓存内容](QueryStringParameters.md)。如果您希望查看 CloudFront 转发到源的查询字符串，请查看 CloudFront 日志文件的 `cs-uri-query` 列中的值。有关更多信息，请参阅 [访问日志（标准日志）](AccessLogs.md)。

## 根据 Cookie 值进行缓存
<a name="cache-hit-ratio-cookies"></a>

如果您将 CloudFront 配置为基于 Cookie 值进行缓存，则可以通过以下方法来改进缓存：
+ 将 CloudFront 配置为仅转发指定的 Cookie 而不是转发所有 Cookie。对于配置为由 CloudFront 转发到源的 Cookie，CloudFront 将转发每个 Cookie 名称和值组合。然后，它单独缓存由源返回的对象，即使这些对象全都相同。

  例如，假设查看器在每个请求中包含两个 Cookie，每个 Cookie 有三个可能的值，并且 Cookie 值的所有组合均可能。对于每个对象，CloudFront 最多会将九个不同的请求转发到您的来源。如果您的源仅基于其中一个 Cookie 返回不同的对象版本，则 CloudFront 会不必要地将更多请求转发到您的源，并且不必要地缓存对象的多个相同版本。
+ 为静态和动态内容创建单独的缓存行为，将 CloudFront 配置成仅为动态内容将 Cookie 转发到源。

  举例而言，假设您的分配只有一个缓存行为，而您希望将分配同时用于动态内容（例如 `.js` 文件）和很少更改的 `.css` 文件。CloudFront 根据 Cookie 值缓存 `.css` 文件的单独版本，这样每个 CloudFront 边缘站点会为每个新 Cookie 值或 Cookie 值的组合将请求转发到您的源。

  如果您创建一个缓存行为，其路径模式为 `*.css` 并且 CloudFront 不根据 Cookie 值进行缓存，则 CloudFront 仅在以下情况下将 `.css` 文件的请求转发到源：边缘站点收到给定 `.css` 文件的第一个请求以及 `.css` 文件过期后收到的第一个请求。
+ 如果可能，请在 Cookie 值对于每个用户唯一（例如用户 ID）时为动态内容创建单独的缓存行为，并为基于少量唯一值变化的动态内容创建单独的缓存行为。

有关更多信息，请参阅 [根据 Cookie 缓存内容](Cookies.md)。如果要查看 CloudFront 转发到源的 Cookie，请查看 CloudFront 日志文件的 `cs(Cookie)` 列中的值。有关更多信息，请参阅 [访问日志（标准日志）](AccessLogs.md)。

## 根据请求标头进行缓存
<a name="cache-hit-ratio-request-headers"></a>

如果您将 CloudFront 配置为基于请求标头进行缓存，则可以通过以下方法来改进缓存：
+ 将 CloudFront 配置为仅基于指定标头进行转发和缓存，而不是基于所有标头转发和缓存。对于您指定的标头，CloudFront 将转发每个标头名称和值组合。然后，它单独缓存由源返回的对象，即使这些对象全都相同。
**注意**  
CloudFront 始终将以下主题中指定的标头转发给您的源：  
CloudFront 如何处理请求并将请求转发到您的 Amazon S3 原始服务器 > [CloudFront 删除或更新的 HTTP 请求标头](RequestAndResponseBehaviorS3Origin.md#request-s3-removed-headers)
CloudFront 如何处理请求及如何将请求转发给您的自定义原始服务器 > [HTTP 请求标头和 CloudFront 行为（自定义源和 Amazon S3 源）](RequestAndResponseBehaviorCustomOrigin.md#request-custom-headers-behavior)

  当您将 CloudFront 配置为基于请求标头进行缓存时，无需更改 CloudFront 转发的标头，仅更改 CloudFront 是否基于标头值缓存对象。
+ 尝试避免基于具有大量唯一值的请求标头进行缓存。

  例如，如果您希望基于用户设备提供不同大小的图像，不要将 CloudFront 配置为基于 `User-Agent` 标头进行缓存，这会导致大量可能的值。而应该将 CloudFront 配置为基于 CloudFront device-type 标头 `CloudFront-Is-Desktop-Viewer`、`CloudFront-Is-Mobile-Viewer`、`CloudFront-Is-SmartTV-Viewer` 和 `CloudFront-Is-Tablet-Viewer` 进行缓存。此外，如果您为平板电脑和桌面返回相同版本的图像，则仅转发 `CloudFront-Is-Tablet-Viewer` 标头，而不是 `CloudFront-Is-Desktop-Viewer` 标头。

有关更多信息，请参阅 [根据请求标头缓存内容](header-caching.md)。

## 不需要压缩时删除 `Accept-Encoding` 标头
<a name="cache-hit-ratio-remove-accept-encoding"></a>

如果未启用压缩 – 由于源不支持它，CloudFront 不支持它，或者内容不可压缩 – 您可以通过将分配中的缓存行为与设置 Custom Origin Header 的源相关联来增加缓存命中率，如下所示：
+ **标头名称**：`Accept-Encoding`
+ **标头值**：（保留为空）

在使用此配置时，CloudFront 会从缓存键中删除 `Accept-Encoding` 标头，并且不在源请求中包含标头。此配置应用于 CloudFront 从该源通过分发所提供的所有内容。

## 通过 HTTP 提供媒体内容
<a name="cache-hit-ratio-http-streaming"></a>

有关优化点播视频 (VOD) 和流式传输视频内容的信息，请参阅[使用 CloudFront 的点播视频和实时流视频](on-demand-streaming-video.md)。

# 使用 Amazon CloudFront Origin Shield
<a name="origin-shield"></a>

CloudFront Origin Shield 是 CloudFront 缓存基础设施中的一个附加层，有助于最大限度地减少源的负载、提高其可用性并降低其运营成本。借助 CloudFront Origin Shield，您可以获得以下优势：

**更好的缓存命中率**  
Origin Shield 可以帮助提高 CloudFront 分配的缓存命中率，因为它在源之前提供了额外的缓存层。当您使用 Origin Shield 时，从 CloudFront 缓存层到源的所有请求都会通过 Origin Shield，从而增加缓存命中的可能性。CloudFront 可以使用从 Origin Shield 到您的源的单个源请求检索每个对象，CloudFront 缓存的所有其他层（边缘站点和[区域边缘缓存](HowCloudFrontWorks.md#CloudFrontRegionaledgecaches)）可以从 Origin Shield 中检索对象。

**减少源负荷**  
Origin Shield 可以进一步减少针对同一对象发送到源的[同时请求](RequestAndResponseBehaviorCustomOrigin.md#request-custom-traffic-spikes)的数量。对不在 Origin Shield 缓存中的内容的请求将与对同一对象的其他请求合并，从而导致发往源的请求只有一个。在源中处理较少的请求可以在高峰负载或意外流量峰值期间保持源的可用性，并且可以降低即时打包、图像转换和数据传出 (DTO) 等方面的成本。

**更好的网络性能**  
当您[在与源之间的延迟最短的](#choose-origin-shield-region) AWS 区域中启用 Origin Shield 时，可以获得更好的网络性能。对于 AWS 区域中的源，CloudFront 网络流量始终保留在高吞吐量 CloudFront 网络上，直至您的源。对于 AWS 外部的源，CloudFront 网络流量一直保留在 CloudFront 网络上，直至到达 Origin Shield（它与源之间具有低延迟连接）。

使用 Origin Shield 需要支付额外费用。有关更多信息，请参阅 [CloudFront 定价](https://aws.amazon.com/cloudfront/pricing/)。

**注意**  
gRPC 请求不支持源护盾。如果支持 gRPC 的分配启用了源护盾，则 gRPC 请求可继续正常运行。但是，请求通过代理直接传输到 gRPC 源，而不通过源护盾。有关更多信息，请参阅 [将 gRPC 与 CloudFront 分配结合使用](distribution-using-grpc.md)。

**Topics**
+ [

## Origin Shield 的使用案例
](#origin-shield-use-cases)
+ [

## 为 Origin Shield 选择 AWS 区域
](#choose-origin-shield-region)
+ [

## 启用 Origin Shield
](#enable-origin-shield)
+ [

## 估算 Origin Shield 成本
](#origin-shield-costs)
+ [

## Origin Shield 高可用性
](#origin-shield-high-availability)
+ [

## Origin Shield 如何与其他 CloudFront 功能进行交互
](#origin-shield-and-other-features)

## Origin Shield 的使用案例
<a name="origin-shield-use-cases"></a>

CloudFront Origin Shield 适用于许多使用案例，包括以下情况：
+ 分布在不同地理区域的查看器
+ 为实时流式处理或动态图像处理提供即时打包的源
+ 具有容量或带宽限制的内部源
+ 使用多个内容分发网络 (CDN) 的工作负载

Origin Shield 可能不太适合其他情况，例如通过代理到达源的动态内容、可缓存性低的内容或不经常请求的内容。

以下各节介绍 Origin Shield 在以下使用案例中的优势。

**Topics**
+ [

### 位于不同地理区域的查看器
](#os-use-cases-global-viewers)
+ [

### 多个 CDN
](#os-use-cases-multi-cdn)

### 位于不同地理区域的查看器
<a name="os-use-cases-global-viewers"></a>

通过 Amazon CloudFront，您本质上可以减少源上的负载，因为 CloudFront 可以从缓存提供服务的请求不会转到源。除了 CloudFront 的[全球边缘站点网络](https://aws.amazon.com/cloudfront/features/#Amazon_CloudFront_Infrastructure)外，[区域边缘缓存](HowCloudFrontWorks.md#CloudFrontRegionaledgecaches)还作为中间层缓存层，为附近地理区域中的查看器提供缓存命中并合并源请求。查看器请求首先路由到附近的 CloudFront 边缘站点，如果对象未在该站点缓存，则请求将发送到区域边缘缓存。

当查看器位于不同的地理区域时，请求可以通过不同的区域边缘缓存进行路由，其中每个缓存都可以向您的源发送对相同内容的请求。但使用 Origin Shield，您可以在区域边缘缓存和源之间获得额外的缓存层。来自所有区域边缘缓存的所有请求都经过 Origin Shield，从而进一步减少源上的负载。下面的示意图对此进行说明。在下图中，源为 AWS Elemental MediaPackage。

**不使用 Origin Shield**

如果没有 Origin Shield，源可能会收到针对相同内容的重复请求，如下图所示。

![\[如果没有 CloudFront Origin Shield，源可能会收到重复的请求。\]](http://docs.aws.amazon.com/zh_cn/AmazonCloudFront/latest/DeveloperGuide/images/origin-shield-without.png)


**使用 Origin Shield**

使用 Origin Shield 有助于减少源上的载荷，如下图所示。

![\[使用 CloudFront Origin Shield，源可能接收更少的重复请求。\]](http://docs.aws.amazon.com/zh_cn/AmazonCloudFront/latest/DeveloperGuide/images/origin-shield-with.png)


### 多个 CDN
<a name="os-use-cases-multi-cdn"></a>

要提供实时视频活动或热门点播内容，您可以使用多个内容分发网络 (CDN)。使用多个 CDN 可以提供某些优势，但这也意味着源可能会收到许多对同一内容的重复请求，每个请求来自不同的 CDN 或同一 CDN 内的不同位置。这些冗余请求可能会对源的可用性产生不利影响，或导致进程（如即时打包或数据传出 (DTO) 到 Internet）的额外运营成本。

当您将 Origin Shield 与将 CloudFront 分配用作其他 CDN 的源相结合时，可以获得以下好处：
+ 减少源收到的冗余请求数量，这有助于减少使用多个 CDN 的负面影响。
+ 跨 CDN 的通用[缓存密钥](controlling-the-cache-key.md)，以及面向源的功能的集中管理。
+ 提高了网络性能。来自其他 CDN 的网络流量在附近的 CloudFront 边缘站点终止，这可能会提供来自本地缓存的命中。如果请求的对象不在边缘站点缓存中，则对源的请求将一直保留在 CloudFront 网络上直至 Origin Shield，从而为源提供高吞吐量和低延迟。如果请求的对象位于 Origin Shield 的缓存中，则完全避免对源的请求。

**重要**  
如果您有兴趣在多 CDN 架构中使用 Origin Shield，并且享有折扣价格，请[联系我们](https://aws.amazon.com/contact-us/)或您的 AWS 销售代表以获取更多信息。可能收取额外费用。

下图显示了当您使用多个 CDN 提供流行的实时视频活动时，此配置如何帮助最大限度地减少源上的负载。在下图中，源为 AWS Elemental MediaPackage。

**不使用 Origin Shield（多个 CDN）**

如果不使用 Origin Shield，源可能会收到针对相同内容的重复请求，每个请求来自不同的 CDN，如下图所示。

![\[该图显示源如何接收重复请求，每个请求来自不同的 CDN。\]](http://docs.aws.amazon.com/zh_cn/AmazonCloudFront/latest/DeveloperGuide/images/origin-shield-without-multi-cdn.png)


**使用 Origin Shield（多个 CDN）**

使用 Origin Shield（将 CloudFront 作为其他 CDN 的源）有助于减少源上的载荷，如下图所示。

![\[该图显示 CloudFront Origin Shield 收到较少的重复请求。\]](http://docs.aws.amazon.com/zh_cn/AmazonCloudFront/latest/DeveloperGuide/images/origin-shield-with-multi-cdn.png)


## 为 Origin Shield 选择 AWS 区域
<a name="choose-origin-shield-region"></a>

在 CloudFront 具有[区域性边缘缓存](HowCloudFrontWorks.md#CloudFrontRegionaledgecaches)的 AWS 区域中，Amazon CloudFront 提供 Origin Shield。启用 Origin Shield 后，可以为 Origin Shield 选择 AWS 区域。您应该选择与源之间具有最低延迟的 AWS 区域。您可以将 Origin Shield 与位于 AWS 区域中的源和不在 AWS 中的源结合使用。

### 对于 AWS 区域中的源
<a name="choose-origin-shield-region-inside-aws"></a>

如果您的源位于 AWS 区域，请首先确定您的源是否位于 CloudFront 提供 Origin Shield 的区域。CloudFront 在以下 AWS 区域提供 Origin Shield。
+ 美国东部（俄亥俄州）–（`us-east-2`）
+ 美国东部（弗吉尼亚州北部）– `us-east-1`
+ 美国西部（俄勒冈）– `us-west-2`
+ 亚太地区（孟买）– (`ap-south-1`)
+ 亚太地区（首尔）– (`ap-northeast-2`)
+ 亚太地区（新加坡）– (`ap-southeast-1`)
+ 亚太地区（悉尼）– `ap-southeast-2`
+ 亚太地区（东京）– (`ap-northeast-1`)
+ 欧洲地区（法兰克福）– `eu-central-1`
+ 欧洲地区（爱尔兰）– `eu-west-1`
+ 欧洲地区（伦敦）– `eu-west-2`
+ 南美洲（圣保罗）– (`sa-east-1`)
+ 中东（阿联酋）– `me-central-1`

**如果您的源位于 CloudFront 提供 Origin Shield 的 AWS 区域**

如果源位于 CloudFront 提供 Origin Shield 的 AWS 区域中（请参阅前面的列表），请在与源相同的区域中启用 Origin Shield。

**如果您的源不在 CloudFront 提供 Origin Shield 的 AWS 区域**

 如果源不在 CloudFront 提供 Origin Shield 的 AWS 区域中，请参阅下表以确定要在哪个区域中启用 Origin Shield。


|  **如果源位于...**  |  **启用 Origin Shield 的位置...**  | 
| --- | --- | 
|  美国西部（加利福尼亚北部）– `us-west-1`  |  美国西部（俄勒冈州）– `us-west-2`  | 
|  非洲（开普敦）– `af-south-1`  |  欧洲地区（爱尔兰）– `eu-west-1`  | 
|  亚太地区（香港）– `ap-east-1`  |  亚太地区（新加坡）– (`ap-southeast-1`)  | 
|  加拿大（中部）– `ca-central-1`  |  美国东部（弗吉尼亚州北部）– `us-east-1`  | 
|  欧洲地区（米兰）– `eu-south-1`  |  欧洲地区（法兰克福）– `eu-central-1`  | 
|  欧洲地区（巴黎）– `eu-west-3`  |  欧洲地区（伦敦）– `eu-west-2`  | 
|  欧洲地区（斯德哥尔摩）– `eu-north-1`  |  欧洲地区（伦敦）– `eu-west-2`  | 
|  中东（巴林）– `me-south-1`  |  亚太地区（孟买）– (`ap-south-1`)  | 

### 对于之外的源AWS
<a name="choose-origin-shield-region-outside-aws"></a>

您可以将 Origin Shield 与本地或不在 AWS 区域中的源结合使用。在这种情况下，请在与源之间的延迟最低的 AWS 区域中启用 Origin Shield。如果您不确定哪个 AWS 区域与源之间的延迟最低，您可以使用以下建议来帮助做出决定。
+ 您可以参阅上表，根据源的地理位置，了解哪个 AWS 区域可能与源之间具有最低延迟的近似情况。
+ 您可以在地理位置靠近源的几个不同 AWS 区域中启动 Amazon EC2 实例，并使用 `ping` 运行一些测试来测量这些区域与源之间的典型网络延迟。

## 启用 Origin Shield
<a name="enable-origin-shield"></a>

您可以启用 Origin Shield 来提高缓存命中率，减少源上的负载，并帮助提高性能。要启用 Origin Shield，请更改 CloudFront 分配中的源设置。Origin Shield 是源的一个属性。对于 CloudFront 分配中的每个源，您可以在为该源提供最佳性能的任何 AWS 区域中单独启用 Origin Shield。

您可以使用 CloudFormation 或 CloudFront API 启用 CloudFront 控制台中的 Origin Shield。

------
#### [ Console ]

**为现有源启用 Origin Shield（控制台）**

1. 登录 AWS 管理控制台，并通过以下网址打开 CloudFront 控制台：[https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home)。

1. 选择具有要更新的源的分配。

1. 选择**源**选项卡。

1. 选择要更新的源，然后选择**编辑**。

1. 对于**启用 Origin Shield **，选择**是**。

1. 对于 **Origin Shield 区域**，选择要在其中启用 Origin Shield 的 AWS 区域。有关选择区域的帮助，请参阅[为 Origin Shield 选择 AWS 区域](#choose-origin-shield-region)。

1. 选择**保存更改**。

当您的分配状态为**已部署**时，Origin Shield 已准备就绪。这需要几分钟。

**为新源启用 Origin Shield（控制台）**

1. 登录 AWS 管理控制台，并通过以下网址打开 CloudFront 控制台：[https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home)。

1. 要在现有分配中创建新源，请执行以下操作：

   1. 选择要在其中创建源的分配。

   1. 选择**创建源**，然后继续执行步骤 3。

   要在新的标准分配中创建新源，请执行以下操作：

   1. 按照以下步骤，在控制台中创建标准分配。有关更多信息，请参阅 [在控制台中创建 CloudFront 分配](distribution-web-creating-console.md#create-console-distribution)。

   1. 在**设置**部分，选择**自定义源设置**。继续执行步骤 3。

1. 对于**启用 Origin Shield **，选择**是**。

1. 对于 **Origin Shield 区域**，选择要在其中启用 Origin Shield 的 AWS 区域。有关选择区域的帮助，请参阅[为 Origin Shield 选择 AWS 区域](#choose-origin-shield-region)。

1. 按照控制台中的步骤完成源或分配创建。

当您的分配状态为**已部署**时，Origin Shield 已准备就绪。这需要几分钟。

------
#### [ CloudFormation ]

要使用 CloudFormation 启用 Origin Shield，请使用 `OriginShield` 资源的 `Origin` 属性类型中的 `AWS::CloudFront::Distribution` 属性。您可以将 `OriginShield` 属性添加到现有 `Origin` 属性，也可以在创建新的 `Origin` 属性时将其包括在内。

以下示例以 YAML 格式显示在美国西部（俄勒冈州）区域 (`OriginShield`) 中启用 `us-west-2` 的语法。有关选择区域的帮助，请参阅[为 Origin Shield 选择 AWS 区域](#choose-origin-shield-region)。此示例仅显示 `Origin` 属性类型，而不显示整个 `AWS::CloudFront::Distribution` 资源。

```
Origins:
- DomainName: 3ae97e9482b0d011.mediapackage.us-west-2.amazonaws.com
  Id: Example-EMP-3ae97e9482b0d011
  OriginShield:
    Enabled: true
    OriginShieldRegion: us-west-2
  CustomOriginConfig:
    OriginProtocolPolicy: match-viewer
    OriginSSLProtocols: TLSv1
```

有关更多信息，请参阅《AWS CloudFormation 用户指南》**的资源和属性参考部分中的 [AWS::CloudFront::Distribution 源](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-origin.html)。

------
#### [ API ]

要使用 AWS 开发工具包或 AWS Command Line Interface (AWS CLI) 对 CloudFront API 启用 Origin Shield，请使用 `OriginShield` 类型。您可以在 `OriginShield` 的 `Origin` 中指定 `DistributionConfig`。有关 `OriginShield` 类型的信息，请参阅《Amazon CloudFront API 参考》**中的以下信息。
+ [OriginShield](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_OriginShield.html)（类型）
+ [Origin](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_Origin.html)（类型）
+ [DistributionConfig](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_DistributionConfig.html)（类型）
+ [UpdateDistribution](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_UpdateDistribution.html)（操作）
+ [CreateDistribution](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_CreateDistribution.html)（操作）

使用这些类型和操作的具体语法因开发工具包、CLI 或 API 客户端而异。有关更多信息，请参阅开发工具包、CLI 或客户端的参考文档。

------

## 估算 Origin Shield 成本
<a name="origin-shield-costs"></a>

您可以根据作为增量层转到 Origin Shield 的请求数量来计算 Origin Shield 的费用。

 对于通过代理到达源的动态（不可缓存）请求，Origin Shield 始终是增量层。动态请求使用 HTTP 方法：`PUT`、`POST`、`PATCH` 和 `DELETE`。

生存时间（TTL）设置小于 3600 秒的 `GET` 和 `HEAD` 请求被视为动态请求。此外，已禁用缓存的 `GET` 和 `HEAD` 请求也被视为动态请求。

要针对动态请求估计 Origin Shield 的费用，请使用以下公式：

动态请求总数 **x** 每 10,000 个请求的 Origin Shield 费用 **/** 10,000

对于采用 HTTP 方法 `GET`、`HEAD` 和 `OPTIONS` 的非动态请求，Origin Shield 有时是一个增量层。启用 Origin Shield 后，可以为 Origin Shield 选择 AWS 区域。对于自然转到与 Origin Shield 位于相同区域中的[区域边缘缓存](HowCloudFrontWorks.md#CloudFrontRegionaledgecaches)的请求，Origin Shield 不是增量层。您不会为这些请求累积 Origin Shield 费用。对于转到与 Origin Shield 位于不同区域中的区域边缘缓存，然后转到 Origin Shield 的请求，Origin Shield 为增量层。您确实需要为这些请求累积 Origin Shield 费用。

要针对可缓存的请求估计 Origin Shield 的费用，请使用以下公式：

可缓存请求总数 **x**（1 - 缓存命中率）**x** 从不同区域的区域边缘缓存转到 Origin Shield 的请求的百分比 **x** 每 10,000 个请求的 Origin Shield 费用 **/** 10,000

有关 Origin Shield 每 10,000 个请求收取的费用的更多信息，请参阅 [CloudFront 定价](https://aws.amazon.com/cloudfront/pricing/)。

## Origin Shield 高可用性
<a name="origin-shield-high-availability"></a>

Origin Shield 利用 CloudFront [区域边缘缓存](HowCloudFrontWorks.md#CloudFrontRegionaledgecaches)功能。其中每个边缘缓存都在一个 AWS 区域中使用至少三个[可用区](https://aws.amazon.com/about-aws/global-infrastructure/regions_az/)以及自动伸缩 Amazon EC2 实例队列而构建。如果 Origin Shield 主位置不可用，则从 CloudFront 位置到 Origin Shield 的连接还会对每个请求使用活动错误跟踪，从而将请求自动路由到 Origin Shield 备用位置。

## Origin Shield 如何与其他 CloudFront 功能进行交互
<a name="origin-shield-and-other-features"></a>

以下各节介绍 Origin Shield 如何与其他 CloudFront 功能进行交互。

### Origin Shield 和 CloudFront 日志记录
<a name="origin-shield-logging"></a>

要查看 Origin Shield 何时处理了请求，必须启用以下选项之一：
+ [CloudFront 标准日志（访问日志）](AccessLogs.md)。免费提供标准日志。
+ [CloudFront 实时访问日志](real-time-logs.md)。使用实时访问日志会产生额外费用。请参阅 [Amazon CloudFront 定价](https://aws.amazon.com/cloudfront/pricing/)。

来自 Origin Shield 的缓存命中在 CloudFront 日志的 `OriginShieldHit` 字段中显示为 `x-edge-detailed-result-type`。Origin Shield 利用 Amazon CloudFront 的[区域边缘缓存](HowCloudFrontWorks.md#CloudFrontRegionaledgecaches)。如果请求从 CloudFront 边缘站点路由到充当 Origin Shield 的区域边缘缓存，则在日志中将其报告为 `Hit`，而不是报告为 `OriginShieldHit`。

### Origin Shield 和源组
<a name="origin-shield-and-origin-group"></a>

Origin Shield 与 [CloudFront 源组](high_availability_origin_failover.md)兼容。由于 Origin Shield 是源的一个属性，因此，对于每个源，请求始终会通过 Origin Shield，即使源是源组的一部分也是如此。对于给定的请求，CloudFront 通过主源的 Origin Shield 将请求路由到源组中的主源。如果该请求失败（根据源组故障转移标准），CloudFront 通过辅助源的 Origin Shield 将请求路由到辅助源。

### Origin Shield 和 Lambda@Edge
<a name="origin-shield-and-lambda-at-edge"></a>

Origin Shield 不会影响 [Lambda@Edge](lambda-at-the-edge.md) 函数的功能，但会影响运行这些函数的 AWS 区域。

当您将 Origin Shield 与 Lambda@Edge 一起使用时，[面向源的触发器](lambda-cloudfront-trigger-events.md)（源请求和源响应）会在启用 Origin Shield 的 AWS 区域中运行。如果 Origin Shield 主位置不可用并且 CloudFront 将请求路由到 Origin Shield 备用位置，则面向源的 Lambda@Edge 触发器也将转为使用备用 Origin Shield 位置。

面向查看器的触发器不受影响。

# 通过 CloudFront 源失效转移来优化高可用性
<a name="high_availability_origin_failover"></a>

对于需要高可用性的场景，您可以使用源故障转移功能设置 CloudFront。要开始使用，您需要创建一个具有两个源的*源组*：一个主源和一个辅助源。如果主源不可用，或返回指示故障的特定 HTTP 响应状态代码，则 CloudFront 自动切换到辅助源。

要设置源故障转移，您必须具有一个至少包含两个源的分配。接下来，为包含两个源（将其中一个设置为主源）的分配创建一个源组。最后，创建或更新缓存行为以使用源组。

要查看用于设置源组和配置特定源故障转移选项的步骤，请参阅[创建源组](#concept_origin_groups.creating)。

在为缓存行为配置源故障转移后，CloudFront 将针对查看器请求执行以下操作：
+ 当出现缓存命中结果时，CloudFront 将返回请求的对象。
+ 当出现缓存未命中时，CloudFront 将请求路由至源组中的主源。
+ 当主源返回不是为故障转移配置的状态代码（如 HTTP 2xx 或 3xx 状态代码）时，CloudFront 将向查看器提供请求的对象。
+ 发生以下任何情况时：
  + 主源返回您为故障转移配置的 HTTP 状态代码
  + CloudFront 无法连接到主源（当 503 设置为失效转移代码时）
  + 来自主源的响应耗时过长（超时）（当 504 设置为失效转移代码时）

  然后，CloudFront 将请求路由到源组中的辅助源。
**注意**  
对于某些使用案例（如流视频内容），您可能希望 CloudFront 快速故障转移到辅助源。要调整 CloudFront 故障转移到辅助源的速度，请参阅[控制源超时和尝试次数](#controlling-attempts-and-timeouts)。

CloudFront 将所有传入的请求路由到主源，即使先前的请求故障转移到辅助源时也是如此。CloudFront 仅在向主源发送请求失败后才向辅助源发送请求。

只有当查看器请求的 HTTP 方法是 `GET`、`HEAD` 或 `OPTIONS` 时，CloudFront 才会故障转移到辅助源。当查看器发送不同的 HTTP 方法（例如 `POST`、`PUT` 等）时，CloudFront 不会进行故障转移。

**注意**  
如果 `OPTIONS` 在缓存行为中未设置为 [缓存的 HTTP 方法](DownloadDistValuesCacheBehavior.md#DownloadDistValuesCachedHTTPMethods)，CloudFront 将无法进行失效转移。

下图阐述了源故障转移的工作原理。

![\[源故障转移的工作原理\]](http://docs.aws.amazon.com/zh_cn/AmazonCloudFront/latest/DeveloperGuide/images/origingroups-overview.png)


**Topics**
+ [

## 创建源组
](#concept_origin_groups.creating)
+ [

## 控制源超时和尝试次数
](#controlling-attempts-and-timeouts)
+ [

## 将源故障转移与 Lambda@Edge 函数结合使用
](#concept_origin_groups.lambda)
+ [

## 将自定义错误页与源故障转移结合使用
](#concept_origin_groups.custom-error)

## 创建源组
<a name="concept_origin_groups.creating"></a><a name="create-origin-groups-procedure"></a>

**创建源组**

1. 登录 AWS 管理控制台，并通过以下网址打开 CloudFront 控制台：[https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home)。

1. 选择要为其创建源组的分配。

1. 选择**源**选项卡。

1. 确保此分配有多个源。否则请添加第二个源。

1. 在**源**选项卡的**（源组**窗格中，选择**创建源组**。

1. 选择源组的源。添加源后，使用箭头设置优先级，即哪个源是主源组，哪个源是辅助源。

1. 为此源组输入一个名称。

1. 选择要用作故障转移条件的 HTTP 状态代码。您可以选择以下状态代码的任意组合：400、403、404、416、500、502、503 或 504。当 CloudFront 收到具有您指定的状态代码之一的响应时，它会故障转移到辅助源。
**注意**  
只有当查看器请求的 HTTP 方法是 `GET`、`HEAD` 或 `OPTIONS` 时，CloudFront 才会故障转移到辅助源。当查看器发送不同的 HTTP 方法（例如 `POST`、`PUT` 等）时，CloudFront 不会进行故障转移。

1. 在**源选择标准**下，指定您的分配在路由查看器请求时，如何选择您的源。您可以选择以下选项。  
**默认值**  
CloudFront 将使用您在**设置**页面上指定的默认源优先级。  
**媒体质量得分**  
CloudFront 跟踪此分数，并使用此分数来确定将请求转发到的第一个源。这也授权 CloudFront 向源组中的备用来源发出异步 `HEAD` 请求，以确定其媒体质量得分。您只能为 AWS Elemental MediaPackage v2 源选择此选项。有关更多信息，请参阅 [媒体质量感知弹性](media-quality-score.md)。

1. 选择**创建源组**。

请务必将您的源组指定为分配缓存行为的源。有关更多信息，请参阅 [名称](DownloadDistValuesOrigin.md#DownloadDistValuesId)。

## 控制源超时和尝试次数
<a name="controlling-attempts-and-timeouts"></a>

默认情况下，CloudFront 长达 30 秒（尝试 3 次连接，每次 10 秒）尝试连接到源组中的主源，之后故障转移到辅助源。对于某些使用案例（如流视频内容），您可能希望 CloudFront 更快地故障转移到辅助源。您可以调整以下设置，以影响 CloudFront 故障转移到辅助源的速度。如果源是辅助源或不属于源组的源，则这些设置会影响 CloudFront 向查看器返回 HTTP 504 响应的速度。

要更快地进行故障转移，请指定更短的连接超时、更少的连接尝试次数，或者同时指定两者。对于自定义源（包括配置*为* 静态网站托管的 Amazon S3 存储桶源），您还可以调整源响应超时。

**源连接超时**  
源连接超时设置影响 CloudFront 尝试建立到源的连接时等待的时间。默认情况下，CloudFront 等待 10 秒以建立连接，但您可以指定 1-10 秒（含）。有关更多信息，请参阅 [连接超时](DownloadDistValuesOrigin.md#origin-connection-timeout)。

**源连接尝试次数**  
源连接尝试设置会影响 CloudFront 尝试连接到源的次数。默认情况下，CloudFront 尝试 3 次进行连接，但您可以指定 1-3（含）。有关更多信息，请参阅 [连接尝试次数](DownloadDistValuesOrigin.md#origin-connection-attempts)。  
对于自定义源（包括配置为静态网站托管的 Amazon S3 存储桶），此设置还影响在源响应超时的情况下 CloudFront 尝试从源获取响应的次数。

**源响应超时**  
源响应超时（也称为源读取超时）影响 CloudFront 从源接收响应（或接收完整响应）的等待时间。默认情况下，CloudFront 等待 30 秒，但您可以指定 1–120 秒（含）。有关更多信息，请参阅 [响应超时](DownloadDistValuesOrigin.md#DownloadDistValuesOriginResponseTimeout)。

### 如何更改这些设置
<a name="controlling-attempts-and-timeouts-how-to"></a>

**在 [CloudFront 控制台](https://console.aws.amazon.com/cloudfront/v4/home)中更改这些设置**
+ 对于新源或新分配，您可以在创建资源时指定这些值。
+ 对于现有分配中的现有源，可在编辑源时指定这些值。

有关更多信息，请参阅 [所有分配设置参考](distribution-web-values-specify.md)。

## 将源故障转移与 Lambda@Edge 函数结合使用
<a name="concept_origin_groups.lambda"></a>

可以将 Lambda@Edge 函数与已使用源组设置的 CloudFront 分配结合使用。要使用 Lambda 函数，请在创建缓存行为时在源组的[源请求或源响应触发器](lambda-cloudfront-trigger-events.md)中指定它。当您将 Lambda@Edge 函数与源组一起使用时，对于单个查看器请求可以触发两次此函数。例如，考虑以下情景：

1. 使用源请求触发器创建 Lambda@Edge 函数。

1. 当 CloudFront（对于缓存未命中）向主源发送请求时会触发一次 Lambda 函数。

1. 主源使用为故障转移配置的 HTTP 状态代码进行响应。

1. 当 CloudFront 向辅助源发送相同的请求时，将再次触发 Lambda 函数。

下图阐述了源故障转移在源请求或响应触发器中包含 Lambda@Edge 函数时的工作方式。

![\[源故障转移如何与 Lambda@Edge 函数结合使用\]](http://docs.aws.amazon.com/zh_cn/AmazonCloudFront/latest/DeveloperGuide/images/origingroups-with-lambda-edge.png)


有关如何使用 Lambda@Edge 触发器的更多信息，请参阅[为 Lambda@Edge 函数添加触发器](lambda-edge-add-triggers.md)。

有关管理 DNS 故障转移的更多信息，请参阅《Amazon Route 53 开发人员指南》**中的[配置 DNS 故障转移](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/dns-failover-configuring.html)。

## 将自定义错误页与源故障转移结合使用
<a name="concept_origin_groups.custom-error"></a>

可以将自定义错误页面与源组结合使用，方式与将其与未为源故障转移设置的源结合使用的方式类似。

当使用源故障转移时，可将 CloudFront 配置为返回主源和/或辅助源的自定义错误页面：
+ **返回主源的自定义错误页** – 如果主源返回未为故障转移配置的 HTTP 状态代码，则 CloudFront 将向查看器返回自定义错误页面。
+ **返回辅助源的自定义错误页** – 如果 CloudFront 从辅助源收到故障状态代码，则 CloudFront 返回自定义错误页。

有关将自定义错误页面与 CloudFront 结合使用的更多信息，请参阅[生成自定义错误响应](GeneratingCustomErrorResponses.md)。

# 管理内容保留在缓存中的时间长度（过期）
<a name="Expiration"></a>

您可控制文件在 CloudFront 转发另一请求到您的源之前留在 CloudFront 缓存中的时长。减少持续时间让您可提供动态内容。增加持续时间意味着您的用户将获得更好的性能，因为直接从边缘缓存提供文件的可能性更大。较长的持续时间还会减少源的负载。

通常，CloudFront 从边缘站点提供文件，直至超出您指定的缓存时长，直至文件过期。文件过期后，边缘站点下次收到对文件的请求时，CloudFront 会将请求转发到源，以确认缓存包含文件的最新版本。来自源的响应取决于文件是否已更改：
+ 如果 CloudFront 缓存已具有最新版本，则源将返回状态代码 `304 Not Modified`。
+ 如果 CloudFront 缓存没有最新版本，则源将返回 `200 OK` 状态代码和文件的最新版本。

如果边缘站点中的某个文件不常被请求，则 CloudFront 可能会移除该文件 – 在文件到期日之前删除文件，以便为最近常被请求的文件腾出空间。

我们建议通过更新分配的缓存策略来管理缓存持续时间。如果您选择不使用缓存策略，则默认 TTL（生存时间）为 24 小时，但您可以更新以下设置来覆盖默认值：
+ 要更改所有匹配相同路径模式的文件的缓存持续时间，可以更改缓存行为的**最小 TTL**、**最大 TTL** 和**默认 TTL** 的 CloudFront 设置。有关各个设置的信息，请参阅[最小 TTL](DownloadDistValuesCacheBehavior.md#DownloadDistValuesMinTTL)、[最大 TTL](DownloadDistValuesCacheBehavior.md#DownloadDistValuesMaxTTL) 和[默认 TTL](DownloadDistValuesCacheBehavior.md#DownloadDistValuesDefaultTTL)。
+ 要更改单个文件的缓存持续时间，您可以配置源以向文件中添加 `Cache-Control` 标头以及 `max-age` 或 `s-maxage` 指令或者添加 `Expires` 标头。有关更多信息，请参阅 [使用标头控制单独对象的缓存时间长度](#expiration-individual-objects)。

有关**最小 TTL**、**默认 TTL** 和**最大 TTL** 如何与 `max-age` 和 `s-maxage` 指令以及 `Expires` 标头字段交互的更多信息，请参阅[指定 CloudFront 缓存对象的时间长度](#ExpirationDownloadDist)。

您还可以控制在 CloudFront 将另一个请求转发到源以再次尝试获取请求的对象之前，在 CloudFront 缓存中保留错误（例如，`404 Not Found`）的时间。有关更多信息，请参阅 [CloudFront 如何处理来自源的 HTTP 4xx 和 5xx 状态代码](HTTPStatusCodes.md)。

**Topics**
+ [

## 使用标头控制单独对象的缓存时间长度
](#expiration-individual-objects)
+ [

## 提供过时（过期）的内容
](#stale-content)
+ [

## 指定 CloudFront 缓存对象的时间长度
](#ExpirationDownloadDist)
+ [

## 使用 Amazon S3 控制台向对象添加标头
](#ExpirationAddingHeadersInS3)

## 使用标头控制单独对象的缓存时间长度
<a name="expiration-individual-objects"></a>

您可以使用 `Cache-Control` 和 `Expires` 标头控制对象保留在缓存中的时间长度。**最小 TTL**、**默认 TTL** 和**最大 TTL** 的设置也会影响缓存时间长度，不过此处只简要说明标头对缓存时间长度的影响：
+ `Cache-Control max-age` 指令让您指定希望对象在 CloudFront 再次从源服务器获取对象之前保留在缓存中的时长（以秒为单位）。CloudFront 支持的最短到期时间为 0 秒。最大值为 100 年。采用以下格式指定值：

  `Cache-Control: max-age=`*秒*

  例如，以下指令告诉 CloudFront 在缓存中将相关对象保留 3600 秒（一小时）：

  `Cache-Control: max-age=3600`

  如果您希望对象在 CloudFront 边缘缓存中保留的时间不同于在浏览器缓存中的保留时间，可以将 `Cache-Control max-age` 和 `Cache-Control s-maxage` 指令一起使用。有关更多信息，请参阅 [指定 CloudFront 缓存对象的时间长度](#ExpirationDownloadDist)。
+ `Expires`标头字段让您使用 [RFC 2616, Hypertext Transfer Protocol -- HTTP/1.1 Section 3.3.1, Full Date](https://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3.1) 中指定的格式指定过期日期和时间，例如：

  `Sat, 27 Jun 2015 23:59:59 GMT`

建议您使用 `Cache-Control max-age` 指令代替 `Expires` 标头字段，以控制对象缓存。如果您同时指定 `Cache-Control max-age` 和 `Expires` 的值，CloudFront 则只使用 `Cache-Control max-age` 的值。

有关更多信息，请参阅 [指定 CloudFront 缓存对象的时间长度](#ExpirationDownloadDist)。

您不能使用查看器的 `Cache-Control` 请求中的 HTTP `Pragma` 或 `GET` 标头字段来强制 CloudFront 返回到对象的源服务器。CloudFront 将忽略查看器请求中的这些标头字段。

有关 `Cache-Control` 和 `Expires` 标头字段的更多信息，请参阅*《RFC 2616，超文本传输协议 – HTTP/1.1》*中以下章节：
+ [第 14.9 节：缓存控制](https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9)
+ [第 14.21 节：过期](https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.21)

## 提供过时（过期）的内容
<a name="stale-content"></a>

CloudFront 支持 `Stale-While-Revalidate` 和 `Stale-If-Error` 缓存控制指令。可以使用这些指令来指定过时内容可供查看器使用多长时间。

**Topics**
+ [

### `Stale-While-Revalidate`
](#stale-while-revalidate)
+ [

### `Stale-If-Error`
](#stale-if-error-only)
+ [

### 同时使用两个指令
](#use-both-stale-directives)

### `Stale-While-Revalidate`
<a name="stale-while-revalidate"></a>

此指令可让 CloudFront 从缓存中提供过时内容，同时 CloudFront 从源异步获取新版本。这样可以缩短延迟，因为查看器无需等待后台获取，即可立即收到来自边缘站点的响应。新内容将在后台加载，以供将来的请求使用。

**Example 示例：`Stale-While-Revalidate`**  
当您将 `Cache-Control` 标头设置为使用这些指令时，CloudFront 会执行以下操作。  

```
Cache-Control: max-age=3600, stale-while-revalidate=600
```

1. CloudFront 会将响应缓存一小时 (`max-age=3600`)。

1. 如果在此持续时间之后发出请求，CloudFront 将提供过时的内容，同时向源发送请求以重新验证和刷新缓存的内容。

1. 在重新验证内容期间，CloudFront 最多可提供 10 分钟 (`stale-while-revalidate=600`) 的过时内容。

**注意**  
CloudFront 提供过时内容的时间最长可达 `stale-while-revalidate` 指令的值或 CloudFront [最大 TTL](DownloadDistValuesCacheBehavior.md#DownloadDistValuesMaxTTL) 的值，以较小者为准。在最大 TTL 持续时间之后，无论 `stale-while-revalidate` 值如何，都无法从边缘缓存中提供过时的对象。

### `Stale-If-Error`
<a name="stale-if-error-only"></a>

此指令可让 CloudFront 在源不可访问或源返回介于 500 和 600 之间的错误代码时从缓存中提供过时内容。这可确保查看器即使在源中断期间也可以访问内容。

**Example 示例：`Stale-If-Error`**  
当您将 `Cache-Control` 标头设置为使用这些指令时，CloudFront 会执行以下操作。  

```
Cache-Control: max-age=3600, stale-if-error=86400
```

1. CloudFront 会将响应缓存一个小时 (`max-age=3600`)。

1. 如果源在此持续时间后断开或返回错误，CloudFront 将在长达 24 小时 (`stale-if-error=86400`) 内继续提供过时内容。

1. 如果您配置了自定义错误响应，则当在指定的 `stale-if-error` 持续时间内遇到错误时，CloudFront 将首先尝试提供过时内容。如果过时内容不可用，CloudFront 将提供您为相应错误状态代码配置的自定义错误响应。有关更多信息，请参阅 [生成自定义错误响应](GeneratingCustomErrorResponses.md)。

**备注**  
CloudFront 提供过时内容的时间最长可达 `stale-if-error` 指令的值或 CloudFront [最大 TTL](DownloadDistValuesCacheBehavior.md#DownloadDistValuesMaxTTL) 的值，以较小者为准。在最大 TTL 持续时间之后，无论 `stale-if-error` 值如何，都无法从边缘缓存中提供过时的对象。
如果您没有配置 `stale-if-error` 或自定义错误响应，CloudFront 将返回过时对象，或将错误响应转发回给查看器，具体取决于所请求的对象是否在边缘缓存中。有关更多信息，请参阅 [如果您尚未配置自定义错误页面，CloudFront​ 如何处理错误](HTTPStatusCodes.md#HTTPStatusCodes-no-custom-error-pages)。

### 同时使用两个指令
<a name="use-both-stale-directives"></a>

`stale-while-revalidate` 和 `stale-if-error` 都是独立的缓存控制指令，您可以将它们一起使用来减少延迟，并为源添加缓冲区以进行响应或恢复。

**Example 示例：同时使用两个指令**  
当您将 `Cache-Control` 标头设置为使用以下指令时，CloudFront 会执行以下操作。  

```
Cache-Control: max-age=3600, stale-while-revalidate=600, stale-if-error=86400
```

1. CloudFront 会将响应缓存一个小时 (`max-age=3600`)。

1. 如果在此持续时间之后发出请求，CloudFront 将在重新验证内容期间提供最长 10 分钟 (`stale-while-revalidate=600`) 的过时内容。

1. 如果在 CloudFront 尝试重新验证内容时原始服务器返回错误，CloudFront 将继续在最长 24 小时 (`stale-if-error=86400`) 内提供过时内容。

缓存是性能和新鲜度之间的平衡。使用 `stale-while-revalidate` 和 `stale-if-error` 之类的指令可以增强性能和用户体验，但要确保配置与您所需的内容新鲜度相一致。过时内容指令最适合需要刷新内容但并非必须具有最新版本的使用案例。此外，如果您的内容没有更改或极少更改，`stale-while-revalidate` 可能会增加不必要的网络请求。相反，可以考虑设置较长的缓存持续时间。

## 指定 CloudFront 缓存对象的时间长度
<a name="ExpirationDownloadDist"></a>

要控制 CloudFront 在将另一个请求发送到源之前在缓存中保留对象的时长，您可以：
+ 设置 CloudFront 分配的缓存行为中的最小、最大和原定设置 TTL 值。您可以在附加到缓存行为的[缓存策略](controlling-the-cache-key.md)中设置这些值（推荐），或在原有缓存设置中进行设置。
+ 将 `Cache-Control` 或 `Expires` 标头包含在来自源的响应中。这些标头还有助于确定浏览器在浏览器缓存中保留对象的时间长度，超过该时间长度后才会将另一个请求发送到 CloudFront。

下表说明了从源发送的 `Cache-Control` 和 `Expires` 标头如何与缓存行为中的 TTL 设置配合使用，从而影响缓存的。


****  

| 源标头 | 最小 TTL = 0 | 最小 TTL > 0 | 
| --- | --- | --- | 
|  **源将 `Cache-Control: max-age` 指令添加到对象**  |  **CloudFront 缓存** CloudFront 缓存对象的时间长度为 `Cache-Control: max-age` 指令或 CloudFront 最长 TTL 的值（取二者中的较小值）。 **浏览器缓存** 浏览器缓存对象的时间长度为 `Cache-Control: max-age` 指令的值。  |  **CloudFront 缓存** CloudFront 缓存取决于 CloudFront 最短 TTL 和最长 TTL 的值以及 `Cache-Control max-age` 指令： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonCloudFront/latest/DeveloperGuide/Expiration.html) **浏览器缓存** 浏览器缓存对象的时间长度为 `Cache-Control: max-age` 指令的值。  | 
|  **源不会将 `Cache-Control: max-age` 指令添加到对象**  |  **CloudFront 缓存** CloudFront 缓存对象的时间长度为 CloudFront 默认 TTL 值。 **浏览器缓存** 视浏览器而定。  |  **CloudFront 缓存** CloudFront 缓存对象的时间长度为 CloudFront 最小 TTL 或默认 TTL（以较大的值为准）。 **浏览器缓存** 视浏览器而定。  | 
|  **源将 `Cache-Control: max-age` 和 `Cache-Control: s-maxage` 指令添加到对象**  |  **CloudFront 缓存** CloudFront 缓存对象的时间长度为 `Cache-Control: s-maxage` 指令或 CloudFront 最长 TTL 的值（取二者中的较小值）。 **浏览器缓存** 浏览器缓存对象的时间长度为 `Cache-Control max-age` 指令的值。  |  **CloudFront 缓存** CloudFront 缓存取决于 CloudFront 最短 TTL 和最长 TTL 的值以及 `Cache-Control: s-maxage` 指令： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonCloudFront/latest/DeveloperGuide/Expiration.html) **浏览器缓存** 浏览器缓存对象的时间长度为 `Cache-Control: max-age` 指令的值。  | 
|  **源将 `Expires` 标头添加到对象**  |  **CloudFront 缓存** CloudFront 缓存对象，直至 `Expires` 标头中的日期或 CloudFront 最长 TTL 的值，以先到者为准。 **浏览器缓存** 浏览器缓存对象，直至 `Expires` 标头中的日期。  |  **CloudFront 缓存** CloudFront 缓存取决于 CloudFront 最短 TTL 和最长 TTL 以及 `Expires` 标头的值： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonCloudFront/latest/DeveloperGuide/Expiration.html) **浏览器缓存** 浏览器缓存对象，直至 `Expires` 标头中的日期和时间。  | 
|  **源将 `Cache-Control: no-cache`、`no-store` 和/或 `private` 指令添加到对象**  |  CloudFront 和浏览器以标头为准。  |  **CloudFront 缓存** CloudFront 缓存对象的时间长度为 CloudFront 最短 TTL 值。[请参阅此表下面的警告](#stale-if-error)。 **浏览器缓存** 浏览器以标头为准。  | 

**警告**  
如果您的最小 TTL 大于 0，CloudFront 将使用缓存策略的最小 TTL，即使源标头中存在 `Cache-Control: no-cache`、`no-store` 和/或 `private` 指令。  
如果源可以访问，CloudFront 会从源获取对象并将其返回给查看器。
如果源无法访问并且最小*或* 最大 TTL 值大于 0，CloudFront 将提供其先前从源获取的对象。
为了避免该行为，请将 `Cache-Control: stale-if-error=0` 指令包含在从源返回的对象中。这样一来，如果源无法访问，以后 CloudFront 就会返回错误消息，作为对请求的响应，而不是返回其先前从源获取的对象。
当源标头包含 `Cache-Control: no-cache`、`no-store` 和/或 `private` 指令时，CloudFront 不会缓存来自 S3 来源的 HTTP 501 状态代码（未实现）。这是 S3 来源的默认行为，即使[最小 TTL](DownloadDistValuesCacheBehavior.md#DownloadDistValuesMinTTL) 设置大于 0 也是如此。

有关如何使用 CloudFront 控制台更改分配的设置的信息，请参阅[更新分配](HowToUpdateDistribution.md)。有关如何使用 CloudFront API 更改分配的设置的信息，请参阅 [UpdateDistribution](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_UpdateDistribution.html)。

## 使用 Amazon S3 控制台向对象添加标头
<a name="ExpirationAddingHeadersInS3"></a>

可以将 `Cache-Control` 或 `Expires` 标头字段添加到 Amazon S3 对象中。为此，请修改对象的元数据字段。

**向 Amazon S3 对象添加 `Cache-Control` 或 `Expires` 标头字段**

1. 按照《Amazon S3 用户指南》**中[在 Amazon S3 控制台中编辑对象元数据](https://docs.aws.amazon.com/AmazonS3/latest/userguide/add-object-metadata.html)主题的**替换系统定义的元数据**部分中的过程进行操作。

1. 对于**键**，选择要添加的标头的名称（**Cache-Control** 或 **Expires**）。

1. 对于**值**，输入标头值。例如，对于 `Cache-Control` 标头，您可以输入 `max-age=86400`。对于 `Expires`，您可以输入到期日期和时间，如 `Wed, 30 Jun 2021 09:28:00 GMT`。

1. 按照此过程的剩余部分操作，以保存元数据更改。

# 根据查询字符串参数缓存内容
<a name="QueryStringParameters"></a>

一些 Web 应用程序使用查询字符串将信息发送到源。查询字符串是 Web 请求的一部分，显示在 `?` 字符之后；该字符串可以包含一个或多个使用 `&` 字符分隔的参数。在以下示例中，查询字符串包括两个参数 *color=red* 和 *size=large*：

`https://d111111abcdef8.cloudfront.net/images/image.jpg?color=red&size=large`

对于分配，您可选择是否希望 CloudFront 将查询字符串转发到源，以及是基于所有参数还是基于选定参数缓存内容。为什么说这可能很有用？ 考虑以下 示例。

假设您的网站提供五种语言。网站的全部五个版本的目录结构和文件名均相同。用户查看网站时，转发到 CloudFront 的请求包括语言查询字符串参数，该参数基于用户选择的语言。您可以将 CloudFront 配置为将查询字符串转发到源，并基于语言参数进行缓存。如果您将 Web 服务器配置为返回指定页面的与所选语言对应的版本，CloudFront 将基于语言查询字符串参数的值分别缓存各个语言版本。

在此示例中，如果您网站的主页为 `main.html`，则以下五个请求将导致 CloudFront 缓存 `main.html` 五次，为语言查询字符串参数的每个值缓存一次：
+ `https://d111111abcdef8.cloudfront.net/main.html?language=de`
+ `https://d111111abcdef8.cloudfront.net/main.html?language=en`
+ `https://d111111abcdef8.cloudfront.net/main.html?language=es`
+ `https://d111111abcdef8.cloudfront.net/main.html?language=fr`
+ `https://d111111abcdef8.cloudfront.net/main.html?language=jp`

请注意以下几点：
+ 一些 HTTP 服务器不处理查询字符串参数，因此，不基于参数值返回对象的不同版本。对于这些源，如果将 CloudFront 配置为将查询字符串参数转发到源，CloudFront 仍根据参数值进行缓存，即使源针对每个参数值向 CloudFront 返回完全相同的对象版本。
+ 要使查询字符串参数与语言结合使用（如上述示例中所述），您必须使用 `&` 字符作为查询字符串参数之间的分隔符。如果您使用不同的分隔符，则可能获得意外结果，具体取决于您为 CloudFront 指定的用作缓存基础的参数以及这些参数在查询字符串中的显示顺序。

  以下示例说明在您使用其他分隔符并将 CloudFront 配置为仅根据 `color` 参数进行缓存时发生的情况：
  + 在以下请求中，CloudFront 根据 `color` 参数值缓存您的内容，但 CloudFront 将值解释为 *red;size=large*：

    `https://d111111abcdef8.cloudfront.net/images/image.jpg?color=red;size=large`
  + 在以下请求中，CloudFront 缓存内容，但不根据查询字符串参数进行缓存。这是因为您将 CloudFront 配置成了基于 `color` 参数进行缓存，但 CloudFront 将以下字符串解释为仅包含 `size` 参数且其值为 *large;color=red*：

    `https://d111111abcdef8.cloudfront.net/images/image.jpg?size=large;color=red`

您可以将 CloudFront 配置为执行下列操作之一：
+ 完全不将查询字符串转发到源。如果您不转发查询字符串，CloudFront 不基于查询字符串参数进行缓存。
+ 将查询字符串转发到源，并基于查询字符串中的所有参数进行缓存。
+ 将查询字符串转发到源，并基于查询字符串中的指定参数进行缓存。

有关更多信息，请参阅 [优化缓存](#query-string-parameters-optimizing-caching)。

**Topics**
+ [

## 针对查询字符串转发和缓存的控制台和 API 设置
](#query-string-parameters-console)
+ [

## 优化缓存
](#query-string-parameters-optimizing-caching)
+ [

## 查询字符串参数和 CloudFront 标准日志（访问日志）
](#query-string-parameters-access-logs)

## 针对查询字符串转发和缓存的控制台和 API 设置
<a name="query-string-parameters-console"></a>

当您在 CloudFront 控制台中创建分配时，CloudFront 会根据源类型为您配置查询字符串转发和缓存。（可选）您可以手动编辑这些设置。有关更多信息，请参阅[所有分配设置参考](distribution-web-values-specify.md)中的以下设置：
+ [查询字符串转发和缓存](DownloadDistValuesCacheBehavior.md#DownloadDistValuesQueryString)
+ [查询字符串允许列表](DownloadDistValuesCacheBehavior.md#DownloadDistValuesQueryStringAllowlist)

要使用 CloudFront API 配置查询字符串转发和缓存，请参阅《Amazon CloudFront API 参考》**中的 [CachePolicy](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_CachePolicy.html) 和 [OriginRequestPolicy](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_OriginRequestPolicy.html)。

## 优化缓存
<a name="query-string-parameters-optimizing-caching"></a>

在将 CloudFront 配置为根据查询字符串参数进行缓存时，可以执行以下步骤来减少 CloudFront 转发到源的请求数。当 CloudFront 边缘站点为对象提供服务时，您可以减少源服务器上的负载并减少延迟，因为从更接近用户的位置为对象提供了服务。

**仅基于源为其返回不同版本的对象的参数进行缓存**  
对于您的 Web 应用程序转发到 CloudFront 的每个查询字符串参数，CloudFront 针对每个参数值将请求转发到您的源，并为每个参数值缓存对象的单独版本。即使不论参数值如何，源始终返回相同的对象时，也是如此。对于多个参数，请求数和对象数相乘。  
建议您将 CloudFront 配置为仅基于源会返回不同版本的查询字符串参数进行缓存，并建议您谨慎考虑基于各参数进行缓存的优点。例如，假设您有一个零售网站。您有六种不同颜色的夹克衫的照片，夹克衫有 10 种不同的尺寸。您的夹克衫图片会显示不同颜色，但没有不同尺寸。要优化缓存，您应将 CloudFront 配置为仅基于颜色参数进行缓存，而非尺寸参数。这增加了 CloudFront 可从缓存满足请求的可能性，这提高了性能并降低了源的负载。

**始终按相同的顺序列出参数**  
查询字符串中参数的顺序很重要。在以下示例中，查询字符串相同，但参数的顺序不同。这将导致 CloudFront 将两个针对 image.jpg 的单独请求转发到源，并缓存对象的两个单独版本：  
+ `https://d111111abcdef8.cloudfront.net/images/image.jpg?color=red&size=large`
+ `https://d111111abcdef8.cloudfront.net/images/image.jpg?size=large&color=red`
建议您始终按相同的顺序列出参数名称，例如字母顺序。

**始终为参数名称和值使用相同的大小写**  
CloudFront 在基于查询字符串参数进行缓存时，会考虑参数名称和值的大小写情况。在以下示例中，查询字符串相同，但参数名称和值的大小写不同。这将导致 CloudFront 将四个针对 image.jpg 的单独请求转发到源，并缓存对象的四个单独版本：  
+ `https://d111111abcdef8.cloudfront.net/images/image.jpg?color=red`
+ `https://d111111abcdef8.cloudfront.net/images/image.jpg?color=Red`
+ `https://d111111abcdef8.cloudfront.net/images/image.jpg?Color=red`
+ `https://d111111abcdef8.cloudfront.net/images/image.jpg?Color=Red`
建议您为参数名称和值使用一致的大小写，例如全小写。

**不要使用与签名 URL 冲突的参数名称**  
如果您使用签名 URL 限制访问您的内容（如果您添加了可信签署人到您的分配），CloudFront 在转发 URL 剩余部分到您的源之前将删除以下查询字符串参数：  
+ `Expires`
+ `Key-Pair-Id`
+ `Policy`
+ `Signature`
如果您使用已签名 URL 并且希望将 CloudFront 配置为将查询字符串转发到源，您自己的查询字符串参数不能命名为 `Expires`、`Key-Pair-Id`、`Policy` 或 `Signature`。

## 查询字符串参数和 CloudFront 标准日志（访问日志）
<a name="query-string-parameters-access-logs"></a>

如果您启用日志记录，则 CloudFront 会记录完整的 URL，包括查询字符串参数。无论您是否将 CloudFront 配置为将查询字符串转发到源都是如此。有关 CloudFront 日志记录的更多信息，请参阅[访问日志（标准日志）](AccessLogs.md)。

# 根据 Cookie 缓存内容
<a name="Cookies"></a>

默认情况下，CloudFront 在处理请求和响应时或在边缘站点中缓存对象时，不考虑 Cookie。如果 CloudFront 收到两个内容相同（仅 `Cookie` 标头中的内容不同）的请求，默认情况下，CloudFront 会将这两个请求视为相同并为它们返回相同的对象。

您可以将 CloudFront 配置为将查看器请求中的部分或所有 Cookie 转发到您的源，以及基于转发的 Cookie 值缓存对象的单独版本。在执行此操作时，CloudFront 将使用查看器请求中的部分或所有 Cookie（无论配置为转发哪些 Cookie）来唯一标识缓存中的对象。

例如，假设 `locations.html` 的请求包含 `country` Cookie，其值为 `uk` 或 `fr`。在将 CloudFront 配置为根据 `country` Cookie 的值缓存对象时，CloudFront 会将 `locations.html` 请求转发到源并包含 `country` Cookie 及其值。源返回 `locations.html`，并且 CloudFront 为具有 `country` Cookie 值 `uk` 的请求缓存对象一次，为具有 Cookie 值 `fr` 的请求缓存一次。

**重要**  
Amazon S3 和部分 HTTP 服务器不处理 Cookie。请不要将 CloudFront 配置为将 Cookie 转发到不处理 Cookie 或不根据 Cookie 改变其响应的源。这可能会导致 CloudFront 将更多请求转发到同一对象的源，从而降低性能并增加源上的负载。考虑到上一个示例，如果您的源不处理 `country` Cookie，或者始终将相同版本的 `locations.html` 返回到 CloudFront，而不考虑 `country` Cookie 的值，请不要将 CloudFront 配置为转发该 Cookie。  
相反，如果您的自定义源依赖于某个特定的 Cookie，或者根据 Cookie 发送不同的响应，请确保将 CloudFront 配置为将该 Cookie 转发到源。否则，CloudFront 会在将请求转发到您的源之前删除该 Cookie。

要配置 Cookie 转发，您需要更新分配的缓存行为。有关缓存行为的更多信息，请参阅[缓存行为设置](DownloadDistValuesCacheBehavior.md)，特别是[转发 Cookie](DownloadDistValuesCacheBehavior.md#DownloadDistValuesForwardCookies) 和[允许列表 Cookie](DownloadDistValuesCacheBehavior.md#DownloadDistValuesAllowlistCookies)部分。

可以配置每个缓存行为以执行下列操作之一：
+ **将所有 Cookie 转发到您的源** – CloudFront 包含查看器在将请求转发到源时发送的所有 Cookie。当源返回响应时，CloudFront 会使用查看器请求中的 Cookie 名称和值来缓存响应。如果源响应包含 `Set-Cookie` 标头，CloudFront 会将其与请求的对象一起返回给查看器。CloudFront 还与从源返回的对象一起缓存 `Set-Cookie` 标头，并在所有缓存命中时将这些 `Set-Cookie` 标头发送给查看器。
+ **转发您指定的 Cookie 集** – CloudFront 将删除查看器发送的未列入允许名单的所有 Cookie，然后再将请求转发到源。CloudFront 使用查看器请求中列出的 cookie 名称和值缓存响应。如果源响应包含 `Set-Cookie` 标头，CloudFront 会将其与请求的对象一起返回给查看器。CloudFront 还与从源返回的对象一起缓存 `Set-Cookie` 标头，并在所有缓存命中时将这些 `Set-Cookie` 标头发送给查看器。

  有关在 Cookie 名称中指定通配符的信息，请参阅[允许列表 Cookie](DownloadDistValuesCacheBehavior.md#DownloadDistValuesAllowlistCookies)。

  如需了解您可以为每个缓存行为转发的 Cookie 名称的当前数量配额或需要请求提高配额，请参阅[查询字符串的配额（旧缓存设置）](cloudfront-limits.md#limits-allowlisted-query-strings)。
+ **不将 Cookie 转发到源** – CloudFront 不根据查看器发送的 Cookie 缓存您的对象。此外，CloudFront 会先删除 Cookie，然后再将请求转发到您的源，并且会在将响应返回给您的查看器之前从响应中删除 `Set-Cookie` 标头。由于这不是使用源资源的最佳方式，因此当您选择此缓存行为时，应确保您的源默认情况下不在源响应中包含 Cookie。

请注意以下有关指定要转发的 Cookie 的信息：

**访问日志**  
如果将 CloudFront 配置为记录请求和 Cookie，则 CloudFront 会记录所有 Cookie 以及所有 Cookie 属性，即使将 CloudFront 配置为不将 Cookie 转发到源，或者将 CloudFront 配置为仅转发特定的 Cookie。有关 CloudFront 日志记录的更多信息，请参阅[访问日志（标准日志）](AccessLogs.md)。

**区分大小写**  
Cookie 的名称和值都要区分大小写。例如，如果将 CloudFront 配置为转发所有 Cookie，并且同一对象的两个查看器请求具有相同的 Cookie（仅大小写不同），则 CloudFront 会将该对象缓存两次。

**CloudFront 对 cookie 进行排序**  
如果将 CloudFront 配置为转发 Cookie（全部或某个子集），则 CloudFront 会在将请求转发到您的源之前以自然顺序按 Cookie 名称对 Cookie 进行排序。  
 不支持以 `$` 字符开头的 Cookie 名称。CloudFront 会在将请求转发到源之前移除该 Cookie。可以删除 `$` 字符或在 Cookie 名称的开头指定其它字符。

**`If-Modified-Since`和`If-None-Match`**  
如果将 CloudFront 配置为转发 Cookie（全部或某个子集），则不支持 `If-Modified-Since` 和 `If-None-Match` 条件请求。

**需要标准名称/值对格式**  
CloudFront 仅在值遵循[标准名称/值对格式](https://tools.ietf.org/html/rfc6265#section-4.1.1)时转发 Cookie 标头，例如：`"Cookie: cookie1=value1; cookie2=value2"`

**禁止对 `Set-Cookie` 标头进行缓存**  
如果将 CloudFront 配置为将 Cookie 转发到源（全部或特定的 Cookie），它还会缓存源响应中收到的 `Set-Cookie` 标头。CloudFront 在其对原始查看器的响应中包括这些 `Set-Cookie` 标头，并将它们包含在从 CloudFront 缓存提供的后续响应中。  
如果您希望在源处接收 Cookie，但不希望 CloudFront 在源的响应中缓存 `Set-Cookie` 标头，请将源配置为使用指定 `Cache-Control` 作为字段名的 `no-cache` 指令来添加 `Set-Cookie` 标头。例如：`Cache-Control: no-cache="Set-Cookie"`。有关更多信息，请参阅*超文本传输协议 (HTTP/1.1)：缓存* 标准中的[响应缓存控制指令](https://tools.ietf.org/html/rfc7234#section-5.2.2)。

**Cookie 名称的最大长度**  
如果将 CloudFront 配置为将特定的 Cookie 转发到源，则配置为由 CloudFront 转发的所有 Cookie 名称的总字节数不能超过 512 与您转发的 Cookie 数的差。例如，如果您将 CloudFront 配置为将 10 个 Cookie 转发到源，则 10 个 Cookie 的名称组合长度不能超过 502 个字节 (512 - 10)。  
如果您将 CloudFront 配置为将所有 Cookie 转发到源，Cookie 名称的长度没有关系。

有关使用 CloudFront 控制台更新分配以使 CloudFront 将 Cookie 转发到源的信息，请参阅[更新分配](HowToUpdateDistribution.md)。有关使用 CloudFront API 更新分配的信息，请参阅《Amazon CloudFront API 参考》**中的 [UpdateDistribution](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_UpdateDistribution.html)。

# 根据请求标头缓存内容
<a name="header-caching"></a>

CloudFront 允许您选择是否希望 CloudFront 将标头转发到源并根据查看器请求中的标头值缓存指定对象的不同版本。这样，您便可以根据用户使用的设备、查看器的位置、查看器使用的语言及各种其他条件来提供内容的不同版本。

**Topics**
+ [

## 标头和分配 – 概述
](#header-caching-web)
+ [

## 选择缓存所基于的标头
](#header-caching-web-selecting)
+ [

## 将 CloudFront 配置为遵守 CORS 设置
](#header-caching-web-cors)
+ [

## 配置基于设备类型的缓存
](#header-caching-web-device)
+ [

## 配置基于查看器语言的缓存
](#header-caching-web-language)
+ [

## 配置基于查看器位置的缓存
](#header-caching-web-location)
+ [

## 配置基于请求协议的缓存
](#header-caching-web-protocol)
+ [

## 为压缩文件配置缓存
](#header-caching-web-compressed)
+ [

## 根据标头进行缓存如何影响性能
](#header-caching-web-performance)
+ [

## 标头和标头值的大小写如何影响缓存
](#header-caching-web-case)
+ [

## CloudFront 返回给查看器的标头
](#header-caching-web-response)

## 标头和分配 – 概述
<a name="header-caching-web"></a>

默认情况下，CloudFront 在边缘站点中缓存对象时不考虑标头。如果源返回两个对象并且这两个对象仅有请求标头中的值不同，CloudFront 仅缓存对象的一个版本。

您可以将 CloudFront 配置为将标头转发到源，这会导致 CloudFront 根据一个或多个请求标头中的值缓存某个对象的多个版本。要根据特定标头的值配置 CloudFront 以缓存对象，请为分配指定缓存行为设置。有关更多信息，请参阅[基于选择的请求标头进行缓存](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/distribution-web-values-specify.html#DownloadDistValuesForwardHeaders)。

例如，假设 `logo.jpg` 的查看器请求包含自定义 `Product` 标头，其值为 `Acme` 或 `Apex`。当您将 CloudFront 配置为基于 `Product` 标头的值缓存对象时，CloudFront 将针对 `logo.jpg` 的请求转发到源并包括 `Product` 标头和标头值。CloudFront 为 `logo.jpg` 标头中值为 `Product` 的请求缓存 `Acme` 一次，为其中值为 `Apex` 的请求缓存一次。

可以在分配中配置每个缓存行为，以执行以下操作之一：
+ 将所有标头转发到源
**注意**  
**对于旧缓存设置** - 如果您将 CloudFront 配置为将所有标头转发到源，则 CloudFront 不会缓存与此缓存行为关联的对象。相反，它会将每个请求发送到源。
+ 转发您指定的标头列表。CloudFront 会基于所有指定标头中的值缓存对象。CloudFront 默认还会转发其转发的标头，但它仅基于指定的标头缓存对象。
+ 仅转发默认标头。在此配置中，CloudFront 不会基于请求标头中的值缓存您的对象。

如需了解您可以为每个缓存行为转发的标头的当前数量配额或请求提高配额，请参阅[标头的配额](cloudfront-limits.md#limits-custom-headers)。

有关使用 CloudFront 控制台更新分配以使 CloudFront 将标头转发到源的信息，请参阅[更新分配](HowToUpdateDistribution.md)。有关使用 CloudFront API 更新现有分配的信息，请参阅《Amazon CloudFront API 参考》**中的 [UpdateDistribution](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_UpdateDistribution.html)。

## 选择缓存所基于的标头
<a name="header-caching-web-selecting"></a>

您可以转发到源以及 CloudFront 进行缓存所基于的标头取决于您的源是 Amazon S3 存储桶还是自定义源。
+ **Amazon S3** – 您可以将 CloudFront 配置为根据特定标头的数量缓存您的对象（请参阅下面的例外情况列表）。但是，建议您避免使用 Amazon S3 源转发标头，除非您需要实施跨源资源共享（CORS），或者想要通过在面向源的事件中使用 Lambda@Edge 来对内容进行个性化设置。
  + 要配置 CORS，您必须转发允许 CloudFront 为启用了跨源资源共享 (CORS) 的网站分配内容的标头。有关更多信息，请参阅 [将 CloudFront 配置为遵守 CORS 设置](#header-caching-web-cors)。
  + 要通过使用转发至您的 Amazon S3 源的标头对内容进行个性化设置，请编写和添加 Lambda@Edge 函数，并将这些函数与要由某个面向源的事件触发的 CloudFront 分配相关联。有关使用标头对内容进行个性化设置的更多信息，请参阅[按国家/地区或设备类型标头个性化内容 - 示例](lambda-examples.md#lambda-examples-redirecting-examples)。

    建议您避免转发并非用于对内容进行个性化设置的标头，因为转发额外的标头可能会降低您的缓存命中率。即，CloudFront 无法从边缘缓存来服务与所有请求中占的比例一样多的请求。
+ **自定义源** – 您可以将 CloudFront 配置为根据以下项以外的任意请求标头的值进行缓存：
  + `Connection`
  + `Cookie` – 如果希望根据 Cookie 转发和缓存，您可以在分配中使用单独的设置。有关更多信息，请参阅 [根据 Cookie 缓存内容](Cookies.md)。
  + `Host (for Amazon S3 origins)`
  + `Proxy-Authorization`
  + `TE`
  + `Upgrade`

  您可以将 CloudFront 配置为基于 `Date` 和 `User-Agent` 标头中的值缓存对象，但建议您不要这样做。这些标头具有大量可能的值，并且基于其值的缓存操作会导致 CloudFront 将更多请求转发到源。

有关 HTTP 请求标头的完整列表以及 CloudFront 如何处理这些标头，请参阅[HTTP 请求标头和 CloudFront 行为（自定义源和 Amazon S3 源）](RequestAndResponseBehaviorCustomOrigin.md#request-custom-headers-behavior)。

## 将 CloudFront 配置为遵守 CORS 设置
<a name="header-caching-web-cors"></a>

如果您已在 Amazon S3 存储桶或自定义源上启用跨源资源共享 (CORS)，则必须选择要转发的特定标头以遵守 CORS 设置。您必须转发的标头因源（Amazon S3 或自定义）及您是否要缓存 `OPTIONS` 响应而异。

**Amazon S3**
+ 如果要缓存 `OPTIONS` 响应，请执行以下操作：
  + 为默认缓存行为设置选择启用 `OPTIONS` 响应缓存的选项。
  + 配置 CloudFront 以转发以下标头：`Origin`、`Access-Control-Request-Headers`、和 `Access-Control-Request-Method`。
+ 如果您不希望缓存 `OPTIONS` 响应，请将 CloudFront 配置为转发 `Origin` 标头以及源所需的任何其他标头（例如 `Access-Control-Request-Headers`、`Access-Control-Request-Method` 或其他）。

**自定义源** – 转发 `Origin` 标头以及源所需的任何其他标头。

要将 CloudFront 配置为根据 CORS 缓存响应，必须将 CloudFront 配置为使用缓存策略转发标头。有关更多信息，请参阅 [使用策略来控制缓存键](controlling-the-cache-key.md)。

有关 CORS 和 Amazon S3 的更多信息，请参阅《Amazon Simple Storage Service 用户指南》**中的[启用跨源资源共享（CORS）](https://docs.aws.amazon.com/AmazonS3/latest/userguide/cors.html)。

## 配置基于设备类型的缓存
<a name="header-caching-web-device"></a>

如果您希望 CloudFront 基于用户查看内容所用设备来缓存不同版本的对象，可将 CloudFront 配置为将合适的标头转发给您的自定义源：
+ `CloudFront-Is-Desktop-Viewer`
+ `CloudFront-Is-Mobile-Viewer`
+ `CloudFront-Is-SmartTV-Viewer`
+ `CloudFront-Is-Tablet-Viewer`

根据 `User-Agent` 标头的值，在将请求转发给您的源之前，CloudFront 将这些标头的值设置为 `true` 或 `false`。如果某个设备归入多个类别中，则多个值可能为 `true`。例如，对于一些平板电脑设备，CloudFront 可能将 `CloudFront-Is-Mobile-Viewer` 和 `CloudFront-Is-Tablet-Viewer` 设置为 `true`。

## 配置基于查看器语言的缓存
<a name="header-caching-web-language"></a>

如果您希望 CloudFront 根据请求中指定的语言缓存对象的不同版本，请将 CloudFront 配置为将 `Accept-Language` 标头转发到源。

## 配置基于查看器位置的缓存
<a name="header-caching-web-location"></a>

如果您希望 CloudFront 根据发出请求的国家/地区缓存对象的不同版本，请将 CloudFront 配置为将 `CloudFront-Viewer-Country` 标头转发到源。CloudFront 自动将发出请求的 IP 地址转换为两个字母的国家/地区代码。要获取可按代码和国家/地区名称排序的易于使用的国家/地区代码列表，请参阅 Wikipedia 条目 [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)。

## 配置基于请求协议的缓存
<a name="header-caching-web-protocol"></a>

如果您希望 CloudFront 根据请求的协议（HTTP 或 HTTPS）缓存对象的不同版本，请配置 CloudFront 以将 `CloudFront-Forwarded-Proto` 标头转发到源。

## 为压缩文件配置缓存
<a name="header-caching-web-compressed"></a>

如果源支持 Brotli 压缩，您可以基于 `Accept-Encoding` 标头进行缓存。仅当源根据 `Accept-Encoding` 标头处理不同内容时基于该标头配置缓存。

## 根据标头进行缓存如何影响性能
<a name="header-caching-web-performance"></a>

在您将 CloudFront 配置为基于一个或多个标头进行缓存并且标头有多个可能值时，CloudFront 会为同一个对象将多个请求转发到您的源服务器。这会降低性能并增加源服务器上的负载。如果不管指定标头的值如何，源服务器均返回相同的对象，建议您不要将 CloudFront 配置为基于该标头进行缓存。

如果您将 CloudFront 配置为转发多个标头，只要值相同，查看器请求中的标头顺序对缓存没有影响。例如，如果一个请求包含标头 A:1,B:2，而另一个请求包含 B:2,A:1，CloudFront 只缓存对象的一个副本。

## 标头和标头值的大小写如何影响缓存
<a name="header-caching-web-case"></a>

根据标头值进行缓存时，CloudFront 不会考虑标头名称的大小写，但是会考虑标头值的大小写：
+ 如果查看器请求同时包含 `Product:Acme` 和 `product:Acme`，CloudFront 仅缓存对象一次。它们之间唯一的差别是标头名称的大小写，这不会影响缓存。
+ 如果查看器请求同时包括 `Product:Acme` 和 `Product:acme`，CloudFront 缓存对象两次，因为在一些请求中具有值 `Acme`，而在另一些请求中具有值 `acme`。

## CloudFront 返回给查看器的标头
<a name="header-caching-web-response"></a>

将 CloudFront 配置为转发和缓存标头不会影响 CloudFront 返回给查看器的标头。CloudFront 返回从源获取的所有标头，只有少数几个例外。有关更多信息，请参阅相关主题：
+ **Amazon S3 源** – 请参阅[CloudFront 删除或更新的 HTTP 响应标头](RequestAndResponseBehaviorS3Origin.md#response-s3-removed-headers)。
+ **自定义源** – 请参阅[CloudFront 移除或替换的 HTTP 响应标头](RequestAndResponseBehaviorCustomOrigin.md#ResponseCustomRemovedHeaders)。