

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

# Amazon ECS 容量與可用性
<a name="capacity-availability-best-practice"></a>

應用程式的可用性至關重要，不僅能提供無錯誤的使用體驗，還有助於減少應用程式的延遲。可用性取決於擁有可存取的資源，以及足夠的容量以滿足需求。 AWS 提供數種機制來管理可用性。對於在 Amazon ECS 上託管的應用程式，這些機制包括自動擴展與可用區域 (AZ)。自動擴展會根據您定義的指標來管理任務或執行個體的數量，而可用區域可讓您將應用程式託管在相互隔離但地理位置相近的位置。

與任務大小一樣，容量與可用性之間也存在必須權衡的取捨。在理想情況下，容量應與需求完全一致。系統將一律保有足夠的容量來處理請求與任務，以達成服務水準目標 (SLO) 目標，包括低延遲與錯誤率。容量不會過高而導致成本過高，也不會過低而造成高延遲與高錯誤率。

自動擴展是一個存在延遲的過程。首先，CloudWatch 必須接收即時指標。接著，CloudWatch 需要彙總這些指標進行分析，根據指標的粒度不同，這個過程可能需要長達幾分鐘。隨後，CloudWatch 會將指標與警示閾值進行比對，判斷資源是否短缺或過剩。為避免系統不穩定，您應將警示設定為：需持續超過設定閾值幾分鐘後，警示才會觸發。此外，佈建新任務與終止不再需要的任務也需要時間。

由於系統中存在這些潛在延遲，您應採用過度佈建方式來保留一些緩衝空間。過度佈建有助於因應短期的需求突增。這也有助於應用程式在不達到飽和狀態的前提下處理更多請求。建議將擴展目標設定在使用率的 60-80% 之間。此舉能幫助應用程式在額外容量仍在佈建過程中時，更好地應對突增的額外需求。

我們建議您過度佈建的另一個原因是，以便您可以快速回應可用區域故障。 AWS 建議從多個可用區域提供生產工作負載。這是因為，如果某個可用區域發生失敗，在剩餘可用區域中執行的任務仍能持續處理需求。如果應用程式在兩個可用區域中執行，則需要將常規任務數量加倍。如此一來，您就可以在任何潛在的故障期間立即提供足夠容量。如果應用程式在三個可用區域中執行，建議將任務數量設定為常規需求的 1.5 倍。也就是說，每需要 2 個任務來處理日常請求，就應部署 3 個任務。

## 最大限度提高擴展速度
<a name="capacity-availability-speed"></a>

自動擴展是一種反應式程序，需要一些時間才能生效。不過，有一些方法可協助將橫向擴充所需的時間降至最低。

**最小化映像大小。**較大的映像需要更長的時間，才能從映像儲存庫下載並解壓縮。因此，保持較小的映像大小可減少容器啟動所需的時間量。若要減小映像大小，您可以遵循下列特定建議：
+ 如果您可以建置靜態二進位檔案或使用 Golang，請建置映像 `FROM` 暫存，並在產生的映像中僅包含二進位應用程式。
+ 使用上游發行版廠商提供的精簡基礎映像，例如 Amazon Linux 或 Ubuntu。
+ 切勿在最終映像中包含任何建置成品。使用多階段建置有助於實現這一點。
+ 盡可能精簡 `RUN` 階段。每個 `RUN` 階段都會建立新的映像層，導致額外的層下載往返次數。透過 `&&` 聯結的多個命令的單一 `RUN` 階段，比多個獨立的 `RUN` 階段產生的層數更少。
+ 若想在最終映像中包含 ML 推論資料等資料，請僅包含啟動與開始處理流量所需的資料。如果隨需從 Amazon S3 或其他儲存擷取資料而不影響服務，請改為將資料儲存於這些位置。

**將映像存放於近處。**網路延遲越高，下載映像的時間就越長。將映像託管在工作負載所在的相同 AWS 區域中的儲存庫中。Amazon ECR 是高效能映像儲存庫，可在提供 Amazon ECS 的每個區域中使用。避免透過網際網路或 VPN 連結下載容器映像。在同一區域中託管映像可改善整體可靠性。此舉可降低不同區域中網路連線問題與可用性問題帶來的風險。此外，您可以實作 Amazon ECR 跨區域複寫來協助解決此問題。

**降低負載平衡器運作狀態檢查閾值。**負載平衡器會先執行運作狀態檢查，再將流量傳送至應用程式。目標群組的預設運作狀態檢查組態設定，可能需要 90 秒或更長時間。在此期間，負載平衡器會檢查運作狀態並接收請求。縮短運作狀態檢查間隔與降低閾值次數，可讓應用程式更快接收流量，減輕其他任務的負載。

**考慮冷啟動效能。**某些應用程式會使用執行時期，例如 Java 執行即時 (JIT) 編譯。編譯過程至少在啟動階段會影響應用程式效能表現。解決方法是將工作負載中對延遲敏感的關鍵部分，改用以不會造成冷啟動效能損耗的程式語言重新編寫。

**使用步進擴展政策而非目標追蹤擴展政策。**您有多個適用於 Amazon ECS 任務的 Application Auto Scaling 選項。目標追蹤是最容易使用的模式。這樣一來，您僅需要為指標設定目標值，例如 CPU 平均使用率。然後，自動縮放器會自動管理獲得該值所需的任務數量。使用步驟擴展，您可以更快對需求變化做出反應，因為您定義了擴展指標的特定閾值，以及超越閾值時要新增或刪除的任務數量。而且，更重要的是，您可以透過最大限度減少閾值警報違反的時間來對需求變化做出非常快速的反應。如需詳細資訊，請參閱《Amazon Elastic Container Service 開發人員指南》**中的[服務自動擴展](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/service-auto-scaling.html)。

如果使用 Amazon EC2 執行個體提供叢集容量，請考量下列建議：

**使用更大的 Amazon EC2 執行個體與更快的 Amazon EBS 磁碟區。**透過使用更大的 Amazon EC2 執行個體與更快的 Amazon EBS 磁碟區，您可以提升映像下載與準備速度。在特定的 Amazon EC2 執行個體系列中，網路與 Amazon EBS 輸送量上限會隨著執行個體大小的增加而提升 (例如，從 `m5.xlarge` 到 `m5.2xlarge`)。此外，您可以自訂 Amazon EBS 磁碟區來提高其輸送量與 IOPS。例如，若使用的是 `gp2` 磁碟區，可選擇提供更高基準輸送量的較大磁碟區。若使用的是 `gp3` 磁碟區，可在建立磁碟區時指定輸送量與 IOPS。

**為執行於 Amazon EC2 執行個體上的任務使用橋接網路模式。**在 Amazon EC2 上使用 `bridge` 網路模式的任務，啟動速度比使用 `awsvpc` 網路模式的任務更快。使用 `awsvpc` 網路模式時，Amazon ECS 會先將彈性網路介面 (ENI) 連接至執行個體，再啟動任務。這會造成額外的延遲。不過，使用橋接聯網存在幾項權衡考量。此類任務不會擁有獨立的安全群組，且在負載平衡面向也會有一些影響。如需詳細資訊，請參閱 *Elastic Load Balancing User Guide* 中的 [Load balancer target groups](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-target-groups.html)。

## 因應需求衝擊
<a name="capacity-availability-shocks"></a>

部分應用程式可能遭遇突發性的大量需求衝擊。發生這種情況的原因有很多：新聞事件、大型促銷活動、媒體事件，或者一些其他會迅速傳播並導致流量在非常短的時間內快速大幅增加的事件。如果未加以規劃，這可能會導致需求快速超過可用資源。

因應需求衝擊的最佳方法是預測需求衝擊並相應地進行規劃。由於自動擴展可能需要一些時間，建議您在需求衝擊開始之前橫向擴充應用程式。為達到最佳效果，建議制定一套結合跨團隊協作的業務計畫，其中應包含採用共用行事曆的緊密協作機制。活動規劃團隊應提前與負責應用程式的團隊緊密合作。這能讓負責應用程式的團隊有足夠時間制定明確的排程計畫。他們可以排定容量，在事件之前進行橫向擴充，並在事件之後進行縮減。如需詳細資訊，請參閱《Application Auto Scaling 使用者指南》中的[排程擴展](https://docs.aws.amazon.com/autoscaling/application/userguide/application-auto-scaling-scheduled-scaling.html)。

如果有企業支援方案，也請務必與您的技術客戶經理 (TAM) 合作。技術客戶經理可以核實您的服務配額，並確保在事件開始之前提高任何必要的配額。如此一來，您就不會意外達到任何服務配額上限。此外，技術客戶經理亦可透過預先啟動負載平衡器等服務的暖機程序，確保活動順利進行。

因應未經排程的需求衝擊是一個更棘手的問題。若幅度夠大，未經排程的衝擊可能會迅速導致需求超過容量，甚至使自動擴展來不及反應。應對未經排程衝擊的最佳方式是過度佈建資源。您必須隨時擁有足夠的資源來因應預期的最大流量需求。

為因應未經排程的需求衝擊而維持最大容量可能耗費頗鉅。若要降低成本影響，可尋找能預測大規模需求衝擊即將發生的領先指標或事件。如果指標或事件能穩定提供足夠的預警時間，則在事件發生時，或指標超過您設定的特定閾值時，立即啟動水平擴展程序。

如果應用程式容易遭遇突發且未經排程的需求衝擊，可考慮為應用程式新增高效能模式。該模式會犧牲非關鍵功能，但保留對客戶而言至關重要的功能。例如，假設應用程式可從產生耗費資源的客製化回應，切換為提供靜態回應頁面。在此案例中，您無需對應用程式進行任何擴展，就能顯著提升輸送量。

最後，您可考慮拆分單體式服務，更高效地因應需求衝擊。如果應用程式是執行成本高昂且擴展速度緩慢的單體式服務，您也許可以擷取或重寫效能關鍵部分，並將其作為個別服務執行。如此，這些新服務便能獨立於非關鍵元件進行擴展。具備單獨橫向擴充應用程式中效能關鍵功能的彈性，不僅可縮短新增容量的時間，也有助於節省成本。