

# 对 CloudFront 中的错误响应状态代码进行故障排除
<a name="troubleshooting-response-errors"></a>

如果 CloudFront 请求源中的对象，并且源返回 HTTP 4xx 或 5xx 状态代码，则 CloudFront 与源之间的通信存在问题。

本主题还包括对使用 Lambda@Edge 或 CloudFront Functions 时的这些状态代码进行故障排除的步骤。

以下主题详细说明了这些错误响应背后的潜在原因，并提供了有关如何诊断和解决潜在问题的分步指导。

**Topics**
+ [HTTP 400 状态代码（错误请求）](http-400-bad-request.md)
+ [HTTP 401 状态代码（未授权）](http-401-unauthorized.md)
+ [HTTP 403 状态代码（无效方法）](http-403-invalid-method.md)
+ [HTTP 403 状态代码（权限被拒绝）](http-403-permission-denied.md)
+ [HTTP 状态代码 404（未找到）](http-404-not-found.md)
+ [HTTP 412 状态代码（前提条件失败）](http-412-precondition-failed.md)
+ [HTTP 500 状态代码（内部服务器错误）](http-500-internal-server-error.md)
+ [HTTP 502 状态代码（无效网关）](http-502-bad-gateway.md)
+ [HTTP 503 状态代码（服务不可用）](http-503-service-unavailable.md)
+ [HTTP 504 状态代码 (Gateway Timeout)](http-504-gateway-timeout.md)

# HTTP 400 状态代码（错误请求）
<a name="http-400-bad-request"></a>

当客户端在请求中发送一些无效数据（例如有效负载或参数中的内容缺失或不正确）时，CloudFront 会返回 400 错误请求。这也可能表示一般客户端错误。

## Amazon S3 源返回 400 错误
<a name="s3-origin-400-error"></a>

如果您将 Amazon S3 源与 CloudFront 分配结合使用，则分配可能会发送带有 HTTP 状态代码 400 错误请求的错误响应，以及类似于以下内容的消息：

*授权标头格式错误；区域 '*<AWS Region>*' 错误；需要 '*<AWS Region>*'*

例如：

*授权标头格式错误；区域“us-east-1”错误；需要“us-west-2”*

以下情况下可能会出现此问题：

1. 您的 CloudFront 分配的来源是一个 Amazon S3 存储桶。

1. 您将 S3 存储桶从一个 AWS 区域移动到了另一个区域。也就是说，您删除了 S3 存储桶，之后您创建了一个同名的新存储桶，但位于与原始 S3 存储桶所在位置不同的 AWS 区域。

要修复此错误，请更新您的 CloudFront 分配，以便在存储桶的当前 AWS 区域中找到 S3 存储桶。

**更新 CloudFront 分配**

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

1. 选择产生此错误的分配。

1. 选择**源和源组**。

1. 查找您移动的 S3 存储桶的源。选中此源旁边的复选框，然后选择**编辑**。

1. 选择**是，编辑**。在选择**是，编辑**之前，您无需更改任何设置。

完成这些步骤后，CloudFront 将重新部署您的分配。部署分配时，您会在**上次修改时间**列下看到**正在部署**状态。部署完成后一段时间，您应停止接收 `AuthorizationHeaderMalformed` 错误响应。

## 应用程序负载均衡器源返回 400 错误
<a name="alb-origin-400-error"></a>

如果您在 CloudFront 分配中使用应用程序负载均衡器源，则导致 400 错误的可能原因包括以下各项：
+ 客户端发送的请求格式错误，不符合 HTTP 规范。
+ 请求标头超过了每个请求行 16 KB、单个标头 16 KB 或整个请求标头 64 KB 的限制。
+ 客户端在发送完整的请求正文之前关闭了连接。

# HTTP 401 状态代码（未授权）
<a name="http-401-unauthorized"></a>

401 未授权响应状态代码指示客户端请求尚未完成，因为该请求缺少所请求资源的有效身份验证凭证。此状态代码与 HTTP `WWW-Authenticate` 响应标头一起发送，其中包含有关客户端在提示用户输入身份验证凭证后如何再次请求资源的信息。有关更多信息，请参阅 [401 Unauthorized](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401)。

在 CloudFront 中，如果源需要使用 `Authorization` 标头来对请求进行身份验证，则 CloudFront 需要将 `Authorization` 标头转发给源，以避免出现 401 未授权错误。当 CloudFront 转发查看器请求到您的源时，默认情况下，CloudFront 会删除一些查看器标头，包括 `Authorization` 标头。为了确保您的源始终能接收到源请求中的 `Authorization` 标头，您可以选择以下几种方式：
+ 使用缓存策略将 `Authorization` 标头添加到缓存键中。源请求会自动包含缓存键中的所有标头。有关更多信息，请参阅 [使用策略来控制缓存键](controlling-the-cache-key.md)。
+ 使用将所有查看器标头转发到源的源请求策略。您无法在源请求策略中单独转发 `Authorization` 标头，但是，当您转发所有查看器标头时，CloudFront 会将 `Authorization` 标头包含在查看器请求中。针对此使用案例，CloudFront 提供了托管式 `AllViewer` 源请求策略。有关更多信息，请参阅 [使用托管式源请求策略](using-managed-origin-request-policies.md)。

有关更多信息，请参阅[如何配置 CloudFront 以将授权标头转发至源？](https://repost.aws/knowledge-center/cloudfront-authorization-header)

# HTTP 403 状态代码（无效方法）
<a name="http-403-invalid-method"></a>

如果您尝试使用尚未在 CloudFront 分配中指定的 HTTP 方法，CloudFront 会返回 403（无效方法）错误。您可以为分配指定以下选项之一：
+ CloudFront 仅转发 `GET` 和 `HEAD` 请求。
+ CloudFront 仅转发 `GET`、`HEAD` 和 `OPTIONS` 请求。
+ CloudFront 转发 `GET`、`HEAD`、`OPTIONS`、`PUT`、`PATCH`、`POST` 和 `DELETE` 请求。如果您选择此选项，则可能需要限制对 Amazon S3 存储桶或自定义源的访问，以便用户无法执行您不希望他们执行的操作。例如，您可能不希望用户具有从您的源中删除对象的权限。

# HTTP 403 状态代码（权限被拒绝）
<a name="http-403-permission-denied"></a>

HTTP 403 错误意味着客户端无权访问所请求的资源。客户端理解了请求，但无法向查看器授予访问权限。以下是 CloudFront 返回此状态代码的常见原因：

**Topics**
+ [备用 CNAME 配置不正确](#alternate-cname-incorrectly-configured)
+ [在 CloudFront 分配或源上配置 AWS WAF](#aws-waf-configured-on-distribution-origin)
+ [自定义源返回 403 错误](#custom-origin-returning-403)
+ [Amazon S3 源返回 403 错误](#s3-origin-403-error)
+ [地理限制返回 403 错误](#geolocation-403)
+ [签名 URL 或签名 Cookie 配置返回 403 错误](#signed-URLs-cookies-403)
+ [堆叠分配导致 403 错误](#stacked-distributions-403)

## 备用 CNAME 配置不正确
<a name="alternate-cname-incorrectly-configured"></a>

确认您为分配指定了正确的 CNAME。要使用备用 CNAME 代替默认 CloudFront URL，请执行以下操作：

1. 在您的 DNS 中创建一条 CNAME 记录，将 CNAME 指向 CloudFront 分配 URL。

1. 在 CloudFront 分配配置中添加该 CNAME。

如果您创建了 DNS 记录但未在 CloudFront 分配配置中添加 CNAME，则该请求将返回 403 错误。有关配置自定义 CNAME 的更多信息，请参阅[通过添加备用域名（CNAME）使用自定义 URL](CNAMEs.md)。

## 在 CloudFront 分配或源上配置 AWS WAF
<a name="aws-waf-configured-on-distribution-origin"></a>

当 AWS WAF 位于客户端和 CloudFront 之间时，CloudFront 无法区分 403 错误代码是由源返回的，还是当请求被阻止时由 AWS WAF 返回的。

要查找 403 状态代码的来源，请检查 AWS WAF Web 访问控制列表（ACL）规则中是否有被阻止的请求。有关更多信息，请参阅以下主题：
+ [AWS WAF web access control lists (web ACLs)](https://docs.aws.amazon.com/waf/latest/developerguide/web-acl.html)
+ [Testing and tuning your AWS WAF protections](https://docs.aws.amazon.com/waf/latest/developerguide/web-acl-testing.html)

## 自定义源返回 403 错误
<a name="custom-origin-returning-403"></a>

如果您使用的是自定义源，则当源中有自定义防火墙配置时，您可能会看到 403 错误。要排除故障，请直接向源发出请求。如果您可以在没有 CloudFront 的情况下重现此错误，则表示是源导致了 403 错误。

如果是自定义源导致了错误，请检查源日志来确定可能导致错误的原因。有关更多信息，请参阅以下故障排除主题：
+ [如何排查 API Gateway 中的 HTTP 403 错误？](https://aws.amazon.com/premiumsupport/knowledge-center/api-gateway-troubleshoot-403-forbidden/ )
+ [如何排查应用程序负载均衡器 HTTP 403 禁止错误？](https://repost.aws/knowledge-center/alb-http-403-error)

## Amazon S3 源返回 403 错误
<a name="s3-origin-403-error"></a>

您可能会由于以下原因看到 403 错误。
+ CloudFront 无权访问 Amazon S3 存储桶。如果未为分配启用来源访问身份（OAI）或源访问控制（OAC）且存储桶为私有的，则可能发生此情况。
+ 所请求 URL 中的指定路径不正确。
+ 所请求的对象不存在。
+ 主机标头是通过 REST API 端点转发的。有关更多信息，请参阅《Amazon Simple Storage Service 用户指南》**中的 [HTTP Host 标头存储桶规范](https://docs.aws.amazon.com/AmazonS3/latest/userguide/VirtualHosting.html#VirtualHostingSpecifyBucket)。
+ 您配置了自定义错误页面。有关更多信息，请参阅 [当您已配置自定义错误页面时 CloudFront​ 如何处理错误](HTTPStatusCodes.md#HTTPStatusCodes-custom-error-pages)。

## 地理限制返回 403 错误
<a name="geolocation-403"></a>

如果您启动了地理限制（也称为地理阻止）来禁止特定地理位置的用户访问您通过 CloudFront 分配所分配的内容，受阻止的用户会收到 403 错误。

有关更多信息，请参阅 [限制您的内容的地理分配](georestrictions.md)。

## 签名 URL 或签名 Cookie 配置返回 403 错误
<a name="signed-URLs-cookies-403"></a>

如果您为分配的行为配置启用了**限制查看器访问**，则不使用签名 Cookie 或签名 URL 的请求将导致 403 错误。有关更多信息，请参阅以下主题：
+ [使用签名 URL 和签名 Cookie 提供私有内容](PrivateContent.md)
+ [我该如何解决与 CloudFront 中的签名 URL 或签名 Cookie 相关的问题？](https://aws.amazon.com/premiumsupport/knowledge-center/cloudfront-troubleshoot-signed-url-cookies/)

## 堆叠分配导致 403 错误
<a name="stacked-distributions-403"></a>

如果您在对源端点的请求链中具有两个或更多分配，CloudFront 将返回 403 错误。我们建议不要将一个分配放在另一个分配之前。

# HTTP 状态代码 404（未找到）
<a name="http-404-not-found"></a>

当客户端尝试访问不存在的资源时，CloudFront 会返回 404（找不到）错误。如果您在 CloudFront 分配中收到此错误，常见原因包括以下各项：
+ 资源不存在。
+ URL 不正确。
+ 返回 404 的自定义源。
+ 返回 404 的自定义错误页面。（任何错误代码都可能转换为 404。） 有关更多信息，请参阅 [当您已配置自定义错误页面时 CloudFront​ 如何处理错误](HTTPStatusCodes.md#HTTPStatusCodes-custom-error-pages)。
+ 意外删除了自定义错误页面，由于请求查找已删除的自定义错误页面，而导致了 404。有关更多信息，请参阅 [如果您尚未配置自定义错误页面，CloudFront​ 如何处理错误](HTTPStatusCodes.md#HTTPStatusCodes-no-custom-error-pages)。
+ 源路径不正确。如果填充了源路径，则在将请求转发到源之前，源路径的值会附加到来自浏览器的每个请求的路径中。有关更多信息，请参阅 [源路径](DownloadDistValuesOrigin.md#DownloadDistValuesOriginPath)。

# HTTP 412 状态代码（前提条件失败）
<a name="http-412-precondition-failed"></a>

当对目标资源的访问被拒绝时，CloudFront 返回 412（前提条件失败）错误代码。在某些情况下，服务器配置为仅在某些条件得到满足后才接受请求。如果任何指定的条件未得到满足，则服务器不允许客户端访问给定的资源。相反，服务器以 412 错误代码进行响应。

CloudFront 中出现 412 错误的常见原因包括：
+ 当 `If-Unmodified-Since` 或 `If-None-Match` 标头定义的条件未得到满足时，对 `GET` 或 `HEAD` 以外的方法发出了有条件请求。在这种情况下，无法发出请求（通常是上传或修改资源）。
+ CloudFront [UpdateDistribution](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_UpdateDistribution.html) API 操作中一个或多个请求字段中的条件评估为 false。

# HTTP 500 状态代码（内部服务器错误）
<a name="http-500-internal-server-error"></a>

HTTP 500 状态代码（内部服务器错误）表示服务器遇到了意外情况，导致其无法完成请求。以下是 Amazon CloudFront 中出现 500 错误的一些常见原因。

**Topics**
+ [原始服务器向 CloudFront 返回 500 错误](#origin-server-500-error)

## 原始服务器向 CloudFront 返回 500 错误
<a name="origin-server-500-error"></a>

原始服务器可能向 CloudFront 返回 500 错误。有关更多信息，请参阅以下故障排除主题：
+ **如果 Amazon S3 返回 500 错误**，请参阅[如何解决来自 Amazon S3 的 HTTP 500 或 503 错误？](https://repost.aws/knowledge-center/http-5xx-errors-s3)
+ **如果 API Gateway 返回 500 错误**，请参阅[如何解决 API Gateway REST API 的 5xx 错误？](https://repost.aws/knowledge-center/api-gateway-5xx-error)
+ **如果弹性负载均衡返回 500 错误**，请参阅《应用程序负载均衡器用户指南》**中的 [HTTP 500: Internal server error](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-troubleshooting.html#http-500-issues)。

如果上面的列表无法解决 500 错误，则问题可能与 CloudFront 接入点返回内部服务器错误有关。可以联系 [支持](https://console.aws.amazon.com/support/home#/) 获取帮助。

# HTTP 502 状态代码（无效网关）
<a name="http-502-bad-gateway"></a>

当 CloudFront 因无法连接至原始服务器而无法提供请求的对象时，CloudFront 返回 HTTP 502 状态代码（无效网关）。

如果您使用的是 Lambda@Edge，则问题可能是 Lambda 验证错误。如果您收到了 HTTP 502 错误以及 `NonS3OriginDnsError` 错误代码，则可能是 DNS 配置问题，导致 CloudFront 无法连接到源。

**Topics**
+ [CloudFront 与自定义源服务器之间的 SSL/TLS 协商失败](#ssl-negotitation-failure)
+ [源没有使用支持的密码/协议进行响应](#origin-not-responding-with-supported-ciphers-protocols)
+ [源中的 SSL/TLS 证书已过期、无效、为自签名或证书链的顺序错误](#ssl-certificate-expired)
+ [源在“源设置”中的指定端口上没有响应](#origin-not-responding-on-specified-ports)
+ [Lambda 验证错误](#http-502-lambda-validation-error)
+ [CloudFront 函数验证错误](#http-502-cloudfront-function-validation-error)
+ [DNS 错误（`NonS3OriginDnsError`）](#http-502-dns-error)
+ [Application Load Balancer 源 502 错误](#cloudfront-alb-502-error)
+ [API Gateway 源 502 错误](#cloudfront-api-gateway-502-error)

## CloudFront 与自定义源服务器之间的 SSL/TLS 协商失败
<a name="ssl-negotitation-failure"></a>

如果您使用的自定义源要求在 CloudFront 与源之间使用 HTTPS，则不匹配的域名可能会导致错误。源上的 SSL/TLS 证书*必须* 包含与您为 CloudFront 分配指定的**源域**或源请求的 `Host` 标头相匹配的域名。

如果域名不匹配，SSL/TLS 握手将失败，CloudFront 将返回 HTTP 状态代码 502（无效网关）并将 `X-Cache` 标头设置为 `Error from cloudfront`。

要确定证书中的域名是否与分配或 `Host` 标头中的**源域**匹配，可以使用在线 SSL 检查程序或 OpenSSL。如果域名不匹配，则有两个选项：
+ 获取包含相应域名的新 SSL/TLS 证书。

  如果您使用 AWS Certificate Manager（ACM），请参阅《AWS Certificate Manager 用户指南》**中的[请求证书](https://docs.aws.amazon.com/acm/latest/userguide/gs-acm-request-public.html)来请求新证书。
+ 更改分配配置，以使 CloudFront 不再尝试使用 SSL 来连接源。

### 在线 SSL 检查程序
<a name="troubleshooting-ssl-negotiation-failure-online-ssl-checker"></a>

要查找 SSL 测试工具，请在 Internet 上搜索“在线 ssl 检查程序。” 通常情况下，您指定域名，该工具将返回有关 SSL/TLS 证书的各种信息。确认在证书的**公用名**或**使用者备用名称**字段中包含您的域名。

### OpenSSL
<a name="troubleshooting-ssl-negotiation-failure-openssl"></a>

要帮助纠正来自 CloudFront 的 HTTP 502 错误，您可以使用 OpenSSL 尝试与源服务器建立 SSL/TLS 连接。如果 OpenSSL 无法建立连接，则可能表明源服务器的 SSL/TLS 配置出错。如果 OpenSSL 能够建立连接，它将返回有关源服务器证书的信息，包括证书的公用名称（`Subject CN` 字段）和使用者备用名称（`Subject Alternative Name` 字段）。

使用以下 OpenSSL 命令测试与源服务器的连接（将*源域*替换为源服务器的域名，如 example.com）：

`openssl s_client -connect origin domain name:443`

如果满足以下条件：
+ 您的源服务器支持具有多个 SSL/TLS 证书的多个域名
+ 您的分配已配置为将 `Host` 标头转发到源

然后，将 `-servername` 选项添加到 OpenSSL 命令中，如以下示例所示（将 *CNAME* 替换为分配中配置的 CNAME）：

`openssl s_client -connect origin domain name:443 -servername CNAME`

## 源没有使用支持的密码/协议进行响应
<a name="origin-not-responding-with-supported-ciphers-protocols"></a>

CloudFront 使用密码和协议连接到源服务器。有关 CloudFront 支持的密码和协议列表，请参阅 [CloudFront 与源之间受支持的协议和密码](secure-connections-supported-ciphers-cloudfront-to-origin.md)。如果您的源在 SSL/TLS 交换中不用这些密码或协议之一进行响应，则 CloudFront 无法连接。可以使用 [SSL Labs](https://www.ssllabs.com/ssltest) 之类的在线工具验证源是否支持密码和协议。在 **Hostname** 字段中键入源的域名，然后选择 **Submit**。查看测试中的 **Common names** 和 **Alternative names** 字段，以确定它们是否与源的域名匹配。测试完成后，在测试结果中查找 **Protocols** 和 **Cipher Suites** 部分，以确定源支持的密码和协议。将它们与 [CloudFront 与源之间受支持的协议和密码](secure-connections-supported-ciphers-cloudfront-to-origin.md) 的列表比较。

## 源中的 SSL/TLS 证书已过期、无效、为自签名或证书链的顺序错误
<a name="ssl-certificate-expired"></a>

如果源服务器返回以下内容，CloudFront 将中断 TCP 连接、返回 HTTP 状态代码 502（无效网关），并将 `X-Cache` 标头设置为 `Error from cloudfront`：
+ 过期的证书
+ 无效的证书
+ 自签名证书
+ 证书链的顺序错误

**注意**  
如果不存在完整的证书链（包括中间证书），CloudFront 将中断 TCP 连接。

有关在自定义源服务器上安装 SSL/TLS 证书的信息，请参阅 [要求在 CloudFront 与您的自定义源之间使用 HTTPS 进行通信](using-https-cloudfront-to-custom-origin.md)。

## 源在“源设置”中的指定端口上没有响应
<a name="origin-not-responding-on-specified-ports"></a>

在 CloudFront 分配中创建源时，您可以为 HTTP 和 HTTPS 流量设置 CloudFront 用于连接到源的端口。默认情况下，这些端口为 TCP 80/443。您可以选择修改这些端口。如果源出于任何原因拒绝这些端口上的流量，或者后端服务器在这些端口上无响应，CloudFront 将无法连接。

要解决这些问题，请检查您的基础设施中运行的任何防火墙并确认它们未阻止支持的 IP 范围。有关更多信息，请参阅《Amazon VPC 用户指南》**中的 [AWS IP 地址范围](https://docs.aws.amazon.com/vpc/latest/userguide/aws-ip-ranges.html)。此外，还要验证您的 Web 服务器是否正在源中运行。

## Lambda 验证错误
<a name="http-502-lambda-validation-error"></a>

如果使用的是 Lambda@Edge，则 HTTP 502 状态代码可能指示未正确设置 Lambda 函数响应格式或包含无效的内容。有关排查 Lambda@Edge 错误的更多信息，请参阅[测试和调试 Lambda@Edge 函数](lambda-edge-testing-debugging.md)。

## CloudFront 函数验证错误
<a name="http-502-cloudfront-function-validation-error"></a>

如果使用的是 CloudFront 函数，HTTP 502 状态代码可能指示 CloudFront 函数正在尝试添加、删除或更改只读标头。此错误不会在测试期间出现，但会在您部署函数并运行请求后出现。要解决此错误，请检查并更新 CloudFront 函数。有关更多信息，请参阅 [更新函数](update-function.md)。

## DNS 错误（`NonS3OriginDnsError`）
<a name="http-502-dns-error"></a>

错误代码为 `NonS3OriginDnsError` 的 HTTP 502 错误表示存在 DNS 配置问题，导致 CloudFront 无法连接到源。如果您从 CloudFront 收到此错误，请确保源的 DNS 配置正确且有效。

当 CloudFront 收到针对已过期或不在缓存中的对象的请求时，它会向源发出请求，以获取该对象。为了成功向源发出请求，CloudFront 会对源域执行 DNS 解析。如果您的域的 DNS 服务出现问题时，CloudFront 将无法解析域名以获取 IP 地址，从而导致 HTTP 502 错误 (`NonS3OriginDnsError`)。要修复此问题，请联系您的 DNS 提供商，或者，如果您使用的是 Amazon Route 53，请参阅[为什么我无法访问使用 Route 53 DNS 服务的网站？](https://aws.amazon.com/premiumsupport/knowledge-center/route-53-dns-website-unreachable/)

要进一步解决该问题，请确保源的根域或顶级域（如 `example.com`）的[权威名称服务器](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/route-53-concepts.html#route-53-concepts-authoritative-name-server)运行正常。您可以通过 [dig](https://en.wikipedia.org/wiki/Dig_(command)) 或 [nslookup](https://en.wikipedia.org/wiki/Nslookup)等工具，使用以下命令查找顶级源的名称服务器：

```
dig OriginAPEXDomainName NS +short
```

```
nslookup -query=NS OriginAPEXDomainName
```

如果您有名称服务器的名称，请使用以下命令针对这些名称查询源的域名，以确保每个查询都会得到响应：

```
dig OriginDomainName @NameServer
```

```
nslookup OriginDomainName NameServer
```

**重要**  
确保使用连接到公共互联网的计算机执行此 DNS 故障排除。CloudFront 使用互联网上的公有 DNS 解析源域，因此在类似环境中进行故障排除非常重要。

如果您的源是一个子域，其 DNS 权限被委托给与根域不同的域名服务器，请确保为该子域正确配置域名服务器 (`NS`) 和授权起始点 (`SOA`) 记录。您可以使用与上述示例类似的命令来检查这些记录。

有关 DNS 的更多信息，请参阅 Amazon Route 53 文档中的[域名系统 (DNS) 概念](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/route-53-concepts.html#route-53-concepts-domain-name-system-dns)。

## Application Load Balancer 源 502 错误
<a name="cloudfront-alb-502-error"></a>

如果您使用应用程序负载均衡器作为源并收到 502 错误，请参阅[如何排查应用程序负载均衡器 HTTP 502 错误？](https://repost.aws/knowledge-center/elb-alb-troubleshoot-502-errors)。

## API Gateway 源 502 错误
<a name="cloudfront-api-gateway-502-error"></a>

如果您使用 API Gateway 并收到 502 错误，请参阅[如何使用 Lambda 代理集成解决来自 API Gateway REST API 的 HTTP 502 错误？](https://repost.aws/knowledge-center/malformed-502-api-gateway)。

# HTTP 503 状态代码（服务不可用）
<a name="http-503-service-unavailable"></a>

HTTP 503 状态代码（服务不可用）通常表示源服务器存在性能问题。在极少数情况下，该代码表示由于边缘站点中的资源限制，CloudFront 暂时无法满足请求。

如果您使用的是 Lambda@Edge 或 CloudFront Functions，则问题可能是执行错误或超出 Lambda@Edge 限制错误。

**Topics**
+ [源服务器没有足够容量来支持请求速率](#http-503-service-unavailable-not-enough-origin-capacity)
+ [由于边缘站点中的资源限制，CloudFront 导致发生错误](#http-503-service-unavailable-limited-resources-at-edge-location)
+ [Lambda@Edge 或 CloudFront Function 执行错误](#http-503-lambda-execution-error)
+ [Lambda@Edge 超出限制](#http-503-lambda-limit-exceeded-error)

## 源服务器没有足够容量来支持请求速率
<a name="http-503-service-unavailable-not-enough-origin-capacity"></a>

当原始服务器不可用或无法处理传入请求时，将返回 HTTP 503 状态代码（服务不可用）。然后，CloudFront 会将错误返回给用户。要解决该问题，请尝试以下解决方案：
+ **如果您使用 Amazon S3 作为原始服务器**：
  + 对于每个分区的 Amazon S3 前缀，您可以每秒执行至少 3500 个 PUT/COPY/POST/DELETE 请求或 5500 个 GET/HEAD 请求。当 Amazon S3 返回 503 减速响应时，这通常表示针对特定 Amazon S3 前缀的请求速率过高。

    由于请求速率针对的是 S3 存储桶中的各个前缀，因此应将对象分布在多个前缀中。随着前缀上的请求速率逐渐提高，Amazon S3 会纵向扩展以分别处理每个前缀的请求。因此，存储桶所处理的总请求速率是前缀数量的倍数。
  + 有关更多信息，请参阅《Amazon Simple Storage Service 用户指南》**中的[性能 Amazon S3 优化](https://docs.aws.amazon.com/AmazonS3/latest/userguide/optimizing-performance.html)。
+ **如果您为原始服务器使用弹性负载均衡，则**：
  + 确保您的后端实例可以响应运行状况检查。
  + 确保您的负载均衡器和后端实例可以处理负载。

  有关更多信息，请参阅：
  + [在使用经典负载均衡器时，如何对返回的 503 错误进行故障排除？](https://repost.aws/knowledge-center/503-error-classic)
  + [如何对应用程序负载均衡器返回的 503（服务不可用）错误进行故障排除？](https://repost.aws/knowledge-center/alb-troubleshoot-503-errors)
+ **使用自定义源时**：
  + 请检查应用程序日志，以确保您的源具有足够资源，如内存、CPU 和磁盘大小。
  + 如果使用 Amazon EC2 作为后端，请确保实例类型具有适当的资源来满足传入请求。有关更多信息，请参阅《Amazon EC2 用户指南》**中的[实例类型](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html)。
+ **使用 API Gateway 时**：
  + 在 API Gateway API 无法接收响应时，此错误与后端集成有关。后端服务器可能：
    + 负载已超出容量，无法处理新的客户端请求。
    + 正在进行临时维护。
  + 要解决此错误，请查看您的 API Gateway 应用程序日志，以确定后端容量、集成或其他方面是否存在问题。

## 由于边缘站点中的资源限制，CloudFront 导致发生错误
<a name="http-503-service-unavailable-limited-resources-at-edge-location"></a>

在极少数情况下，CloudFront 无法将请求路由到下一个可用的最佳边缘站点并因此无法满足请求，此时您将收到此错误。当您对 CloudFront 分配执行负载测试时，此错误很常见。为帮助防止发生此情况，请遵循[对 CloudFront 进行负载测试](load-testing.md) 指南，以避免 503（超出容量）错误。

如果在生产环境中发生这种情况，请联系 [支持](https://console.aws.amazon.com/support/home#/)。

## Lambda@Edge 或 CloudFront Function 执行错误
<a name="http-503-lambda-execution-error"></a>

如果您使用的是 Lambda@Edge 或 CloudFront Functions，则 HTTP 503 状态代码可能指示您的函数返回了执行错误。

有关如何识别和解决 Lambda@Edge 错误的详细信息，请参阅[测试和调试 Lambda@Edge 函数](lambda-edge-testing-debugging.md)。

有关对 CloudFront Functions 进行测试的更多信息，请参阅[测试函数](test-function.md)。

## Lambda@Edge 超出限制
<a name="http-503-lambda-limit-exceeded-error"></a>

如果您使用的是 Lambda@Edge，则 HTTP 503 状态代码可能表明 Lambda 返回了错误。此错误可能是由于下列原因之一导致的：
+ 函数执行数量超过了 Lambda 为限制 AWS 区域中的执行数量而设置的配额之一（并发执行或调用频率）。
+ 函数超出了 Lambda 函数超时配额。

有关 Lambda@Edge 配额的更多信息，请参阅 [有关 Lambda@Edge 的配额](cloudfront-limits.md#limits-lambda-at-edge)。有关如何识别和解决 Lambda@Edge 错误的详细信息，请参阅[测试和调试 Lambda@Edge 函数](lambda-edge-testing-debugging.md)。您还可以查看**《AWS Lambda 开发人员指南》中的 [Lambda 服务配额](https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-limits.html)。

# HTTP 504 状态代码 (Gateway Timeout)
<a name="http-504-gateway-timeout"></a>

HTTP 504 状态代码（网关超时）指示当 CloudFront 将请求转发至源后（因为请求的对象不在边缘缓存中），发生了以下情况之一：
+ 源将 HTTP 504 状态代码返回到 CloudFront。
+ 源在请求过期前未响应。

如果流量被防火墙或安全组阻止进入源，或者无法在 Internet 上访问源，CloudFront 将返回 HTTP 504 状态代码。请首先检查是否存在这些问题。然后，如果访问没有问题，请探究应用程序延迟和服务器超时，以帮助您确定并解决问题。

**Topics**
+ [将您的源服务器上的防火墙设置为允许 CloudFront 流量](#http-504-gateway-timeout-configure-firewall)
+ [将您的源服务器上的安全组设置为允许 CloudFront 流量](#http-504-gateway-timeout-configure-security-groups)
+ [使自定义源服务器在 Internet 上可访问](#http-504-gateway-timeout-make-origin-accessible)
+ [查找并修复源服务器上来自应用程序的延迟响应](#http-504-gateway-timeout-slow-application)

## 将您的源服务器上的防火墙设置为允许 CloudFront 流量
<a name="http-504-gateway-timeout-configure-firewall"></a>

如果您的源服务器上的防火墙阻止 CloudFront 流量，CloudFront 将返回 HTTP 504 状态代码，所以在检查其他问题之前，务必确保不是这个问题的原因。

您用于确定这是否是与您的防火墙相关的问题的方法取决于源服务器使用的系统：
+ 如果您使用的是 Linux 服务器上的 IPTable 防火墙，则可以搜索帮助您使用 IPTable 的工具和信息。
+ 如果您使用的是 Windows 服务器上的 Windows 防火墙，请参阅 Microsoft 文档中的[添加或编辑防火墙规则](https://technet.microsoft.com/en-us/library/cc753558(v=ws.11).aspx)。

当您评估源服务器上的防火墙配置时，基于发布的 IP 地址范围查找阻止来自 CloudFront 边缘站点的流量的任何防火墙或安全规则。有关更多信息，请参阅 [CloudFront 边缘服务器的位置和 IP 地址范围](LocationsOfEdgeServers.md)。

如果 CloudFront IP 地址范围已允许连接至您的源服务器，请确保更新您的服务器的安全规则以合并更改。您可以订阅 Amazon SNS 主题并且在更新 IP 地址范围文件时接收通知。收到该通知后，您可以使用代码检索该文件、解析文件并根据您的当地环境做出相应调整。有关更多信息，请参阅 AWS 新闻博客上的[通过 Amazon SNS 订阅 AWS 公共 IP 地址范围](https://aws.amazon.com/blogs/aws/subscribe-to-aws-public-ip-address-changes-via-amazon-sns/)。

## 将您的源服务器上的安全组设置为允许 CloudFront 流量
<a name="http-504-gateway-timeout-configure-security-groups"></a>

如果您的源使用 Elastic Load Balancing，请检查 [ELB 安全组](https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-security-groups.html)并确保安全组允许来自 CloudFront 的入站流量。

您还可以使用 AWS Lambda 自动更新您的安全组，以允许来自 CloudFront 的入站流量。

## 使自定义源服务器在 Internet 上可访问
<a name="http-504-gateway-timeout-make-origin-accessible"></a>

如果 CloudFront 由于自定义源服务器未在 Internet 上公开而无法对其进行访问，CloudFront 将返回 HTTP 504 错误。

CloudFront 边缘站点通过 Internet 连接到源服务器。如果自定义源位于私有网络上，CloudFront 则无法访问它。因此，您无法使用私有服务器（包括[内部经典负载均衡器](https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-internal-load-balancers.html)）作为 CloudFront 的源服务器。

要检查互联网流量是否可以连接到原始服务器，请运行以下命令（其中 *OriginDomainName* 是您的服务器的域名）：

对于 HTTPS 流量：
+ nc -zv *OriginDomainName* 443
+ telnet *OriginDomainName* 443

对于 HTTP 流量：
+ nc -zv *OriginDomainName* 80
+ telnet *OriginDomainName* 80

## 查找并修复源服务器上来自应用程序的延迟响应
<a name="http-504-gateway-timeout-slow-application"></a>

服务器超时通常是应用程序响应时间过长或超时值设置得过低的结果。

帮助避免 HTTP 504 错误的快速解决方法是为您的分配设置一个较高的 CloudFront 超时值。但是，建议您首先确保解决与应用程序和源服务器相关的任何性能和延迟问题。然后，您可以设置一个合理的超时值，以帮助防止 HTTP 504 错误并向用户提供良好的响应能力。

以下是您要查找性能问题并进行更正可以采取的步骤的概述：

1. 测量您的 Web 应用程序的典型和高负载延迟 (响应能力)。

1. 添加其他资源，如 CPU 或内存 (如果需要)。采取解决问题的其他步骤，如优化数据库查询以适应高负载场景。

1. 如果需要，调整您的 CloudFront 分配的超时值。

以下是关于每个步骤的详细信息。

### 测量典型和高负载延迟
<a name="http-504-gateway-timeout-slow-application-measure-latency"></a>

要确定一个或多个后端 Web 应用程序服务器是否遇到高延迟，请在每个服务器上运行以下 Linux curl 命令：

```
curl -w "DNS Lookup Time: %{time_namelookup} \nConnect time: %{time_connect} \nTLS Setup: %{time_appconnect} \nRedirect Time: %{time_redirect} \nTime to first byte: %{time_starttransfer} \nTotal time: %{time_total} \n" -o /dev/null https://www.example.com/yourobject
```

**注意**  
如果您在服务器上运行的是 Windows，则可以搜索并下载用于 Windows 运行类似命令的 curl。

您在测量并评估在您的服务器上运行的应用程序的延迟时，请注意以下事项：
+ 延迟值是相对于每个应用程序的。但是，合理的做法是第一个字节的时间采用毫秒而不是秒或更大的单位。
+ 如果您在正常负载下测量应用程序延迟且结果正常，请注意查看器在高负载下可能仍会遇到超时。当存在高需求时，服务器可能已延迟响应或根本未响应。为了帮助防止高负载延迟问题，请检查您的服务器的资源，如 CPU、内存和磁盘读写情况，以确保您的服务器具有针对高负载进行扩展的容量。

  您可以运行以下 Linux 命令来检查 Apache 进程所使用的内存：

  `watch -n 1 "echo -n 'Apache Processes: ' && ps -C apache2 --no-headers | wc -l && free -m"`
+ 服务器上的 CPU 使用率高可能会大幅降低应用程序的性能。如果您对后端服务器使用的是 Amazon EC2 实例，请检查服务器的 CloudWatch 指标以查看 CPU 利用率。有关更多信息，请参阅 [Amazon CloudWatch 用户指南](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/WhatIsCloudWatch.html)。或者，如果您使用的是自己的服务器，请参阅服务器帮助文档来了解有关如何检查 CPU 利用率的说明。
+ 检查在高负载下是否存在其他潜在问题，如存在大量请求时数据库查询运行缓慢。

### 添加资源并优化服务器和数据库
<a name="http-504-gateway-timeout-slow-application-add-resources"></a>

在您评估应用程序和服务器的响应能力后，请确保您有用于典型流量和高负载情况的足够资源：
+ 如果您有自己的服务器，请确保它具有足够的 CPU、内存和磁盘空间来处理查看器请求 (根据您的评估)。
+ 如果使用 Amazon EC2 实例作为后端服务器，请确保实例类型具有适当的资源来满足传入请求。有关更多信息，请参阅《Amazon EC2 用户指南》**中的[实例类型](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html)。

此外，请考虑以下帮助避免超时的优化步骤：
+ 如果 curl 命令返回的第一个字节的时间值似乎很高，请采取改进您的应用程序性能的步骤。提高应用程序响应能力反过来将有助于减少超时错误。
+ 优化数据库查询以确保它们可以处理大量请求，而不会降低性能。
+ 在您的后端服务器上设置[保持连接 (持久性)](https://www.w3.org/Protocols/HTTP/1.1/draft-ietf-http-v11-spec-01) 连接。该选项有助于避免在必须为后续请求或用户重新建立连接时发生的延迟。
+ **如果您使用弹性负载均衡作为源**，则导致 504 错误的可能原因如下：
  + 负载均衡器未能在连接超时到期（10 秒）之前建立与目标的连接。
  + 负载均衡器与目标建立了连接，但目标在空闲超时周期到期之前未响应。
  + 子网的网络访问控制列表（ACL）不允许在临时端口（1024-65535）上存在从目标到负载均衡器节点的流量。
  + 目标返回的 content-length 标头大于整个正文。负载均衡器因等待缺少的字节而超时。
  + 目标是 Lambda 函数，而 Lambda 在连接超时过期之前没有响应。

  有关减少延迟的更多信息，请参阅[如何对 ELB 经典负载均衡器上的高延迟进行故障排除？](https://repost.aws/knowledge-center/elb-latency-troubleshooting)
+ **如果您使用 MediaTailor 作为源**，则导致 504 错误的可能原因如下：
  + 如果相对 URL 处理不当，MediaTailor 可能会从播放器收到格式错误的 URL。
  + 如果 MediaPackage 是 MediaTailor 的清单来源，那么 MediaPackage 404 清单错误可能导致 MediaTailor 返回 504 错误。
  + 向 MediaTailor 原始服务器发出的请求需要 2 秒以上的时间才能完成。
+ **如果您使用 Amazon API Gateway 作为源**，则导致 504 错误的可能原因如下：
  + 集成请求所花的时间比 API Gateway REST API 最大集成超时参数更长。有关更多信息，请参阅[如何使用 API Gateway 解决 API HTTP 504 超时错误？](https://repost.aws/knowledge-center/api-gateway-504-errors)

### 如果需要，请调整 CloudFront 超时值
<a name="http-504-gateway-timeout-slow-application-adjust-timeout"></a>

如果您已评估并解决低应用程序性能、源服务器容量及其他问题，但查看器仍遇到 HTTP 504 错误，则您应考虑更改在您的分配中为源响应超时指定的时间。有关更多信息，请参阅 [响应超时](DownloadDistValuesOrigin.md#DownloadDistValuesOriginResponseTimeout)。