

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# HTTP 504 狀態碼 (閘道逾時)
<a name="http-504-gateway-timeout"></a>

HTTP 504 狀態碼 (閘道逾時) 代表當 CloudFront 將請求轉送回到原始伺服器時 (因為請求的物件未在邊緣快取中) 發生了下列其中一個事件：
+ 原始伺服器將 HTTP 504 狀態碼傳回 CloudFront。
+ 原始伺服器未在請求逾期之前回應。

當流量受到防火牆或安全群組封鎖而無法傳入原始伺服器，或是無法從網際網路存取該原始伺服器，則 CloudFront 將傳回 HTTP 504 狀態碼。請先查看這些問題。如果可以正常存取，請探索應用程式延遲和伺服器逾時，以協助您找出問題並進行修正。

**Topics**
+ [設定原始伺服器的防火牆來允許 CloudFront 流量](#http-504-gateway-timeout-configure-firewall)
+ [設定原始伺服器的安全群組來允許 CloudFront 流量](#http-504-gateway-timeout-configure-security-groups)
+ [設定您的自訂原始伺服器可從網際網路存取](#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 的傳入流量。

## 設定您的自訂原始伺服器可從網際網路存取
<a name="http-504-gateway-timeout-make-origin-accessible"></a>

如果 CloudFront 無法存取自訂原始伺服器是因為此伺服器無法從網際網路公開存取，CloudFront 將傳回 HTTP 504 錯誤。

CloudFront 節點是經由網際網路連接到原始伺服器。如果您的自訂原始伺服器位於私有網路，則 CloudFront 無法與其連線。基於上述原因，您不能使用包括[內部 Classic Load Balancer](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>

導致伺服器逾時發生的原因通常是等候應用程式回應的時間過長，或是設定的逾時值過短。

直接為分佈設定較高 CloudFront 逾時值，就能快速修正，協助避免 HTTP 504 錯誤的發生。但是，我們建議您先排除任何與應用程式和原始伺服器有關的效能和延遲問題。接著您可以設定合理的逾時值，協助避免 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 命令傳回的 Time to First Byte 值看似很高，請採取適當步驟以提升應用程式的效能。提升應用程式回應能力將有助於減少逾時錯誤。
+ 調校資料庫查詢以確保其可處理大量請求，且不會降低效能。
+ 在您的後端伺服器上設定 [keep-alive (persistent)](https://www.w3.org/Protocols/HTTP/1.1/draft-ietf-http-v11-spec-01) (保持活動 (持續)) 連線。當伺服器必須為後續請求或使用者重新建立連線時，此選項可避免此時發生延遲。
+ **如果您使用 Elastic Load Balancing 做為原始伺服器**，下列是造成 504 錯誤的可能原因：
  + 負載平衡器無法在連線逾時過期 (10 秒) 之前建立對目標的連線。
  + 負載平衡器建立了對目標的連線，但目標未在閒置逾時期間經過之前回應。
  + 子網路的網路存取控制清單 (ACL) 不允許從目標到暫時性連接埠 (1024-65535) 上負載平衡器節點的流量。
  + 目標傳回的內容長度標頭大於實體主體。負載平衡器等候遺失的位元組時逾時。
  + 目標是 Lambda 函數，且 Lambda 未在連線逾時期間經過之前回應。

  如需減少延遲的詳細資訊，請參閱[如何對 ELB Classic Load Balancer 上的高延遲進行疑難排解？](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)。