App Engine 標準環境使用者適用的 App Engine 彈性環境

本指南為熟悉標準環境的使用者介紹 App Engine 彈性環境,說明兩種環境之間的相似之處與主要差異,並提供這兩種環境中的應用程式架構建議。

如需瞭解標準環境與彈性環境中可用服務的對應情況,請參閱從標準環境將服務遷移至彈性環境一文。

相似之處與主要差異

兩種環境均提供 App Engine 的部署、服務和資源調度基礎架構。主要差異在於環境執行應用程式、應用程式存取外部服務、在本機執行應用程式以及應用程式資源調度的方式。更多資訊請參閱選擇環境中關於差異的高階概要說明。

應用程式的執行方式

在標準環境中,應用程式會在沙箱內含的輕量級執行個體上運作。沙箱會限制應用程式的功能,例如沙箱只允許應用程式使用有限的二進位檔程式庫,且應用程式無法寫入磁碟。標準環境還會限制應用程式可用的 CPU 和記憶體選項。由於這些限制,App Engine 標準應用程式大多為無狀態的網路應用程式,其特色是能夠快速回應 HTTP 要求。

相反地,彈性環境會在限制較少的 Google Compute Engine 虛擬機器 (VM) Docker 容器中執行應用程式。例如,您可以選擇使用任何一種程式設計語言和任何程式庫、寫入磁碟,甚至可以執行多個程序。彈性環境還可讓您為執行個體選擇任何一種 Compute Engine 機器類型,使應用程式能夠存取更多的記憶體和 CPU。

存取外部服務

在標準環境中,應用程式通常會透過內建的 google.appengine API 存取 Datastore 等服務,但彈性環境已不再提供這些 API,您必須改用 Google Cloud 用戶端程式庫。這些用戶端程式庫的用途極為廣泛,代表應用程式具有更高的可攜性。如有需要,在彈性環境中執行的應用程式通常不必經過大幅修改,就能在 Google Kubernetes EngineCompute Engine 上執行。

本機開發

標準環境通常會使用 App Engine SDK 在本機執行應用程式。SDK 負責執行應用程式並模擬 App Engine 服務。彈性環境則不再使用 SDK 執行應用程式,而是應該採用標準網路應用程式的撰寫方法,撰寫適合彈性環境的應用程式,使其能在任何地方執行。如前所述,彈性環境只會在 Docker 容器中執行應用程式。這表示您在本機測試應用程式時,只要直接執行應用程式即可。舉例來說,如要使用 Django 執行 Python 應用程式,只需執行 python manage.py runserver 即可。

另一個主要差異是,彈性環境應用程式在本機執行時會使用實際的 Cloud Platform 服務,如 Datastore。請使用單獨專案進行本機測試;若有模擬器可用,請使用模擬器。

資源調度特性

雖然兩種環境都使用 App Engine 的自動調整資源配置基礎架構,但兩者的資源調度方式卻截然不同。標準環境能夠非常快速地從沒有執行個體擴充到數千個執行個體。相較之下,彈性環境必須至少具有一個執行中的應用程式執行個體,並且需要更長的資源調度時間來回應流量。

標準環境使用量身打造的自動調度資源演算法,彈性環境則使用 Compute Engine 自動配置器。請注意,彈性環境不支援 Compute Engine 提供的所有自動調度資源選項。App Engine 會尊重您在符合設定的地區中已保留的任何 Compute Engine VM 預留項目。在暫時性資源不足期間,如果您有 VM 保留空間,就更有可能獲得資源分配。

開發人員應該在符合特定條件的情形下測試應用程式行為。舉例來說,在呼叫具有較高延遲的遠端服務期間,應用程式從受到 CPU 限制變成受到 I/O 限制時,您應該驗證自動調度資源的回應方式。

健康狀態檢查

標準環境不會使用健康狀態檢查來判斷是否要將流量傳送到執行個體。彈性環境允許應用程式開發人員自行編寫健康狀態檢查處理常式,供負載平衡器用來判斷是否要將流量傳送至執行個體,以及是否要執行自動修復作業。開發人員在新增健康狀態檢查的邏輯時,應特別留意。舉例來說,如果健康狀態檢查呼叫外部服務,則該服務的暫時性故障會導致所有執行個體的健康狀態不良,可能因此造成連鎖性故障問題。

超載時降低要求數

應用程式可以在超載時降低要求數,這是避免發生連鎖性故障的策略之一。這項功能內建在標準環境中的流量轉送層級。對於彈性環境中 QPS 極高的應用程式,我們建議開發人員為其建構這項功能,以透過限制並行要求數量的方式,降低超載流量。

您可以建立具有執行個體數上限的版本,藉此驗證您的彈性環境應用程式是否容易受到這類故障的影響。接著逐步穩定增加流量,直到要求數下降為止。您必須確保應用程式在超載期間仍可通過健康狀態檢查。

針對 Java,使用 Jetty 執行階段的 Java 應用程式可設定服務品質篩選器,以實作超載流量捨棄機制。您可以使用這項功能設定應用程式可處理的並行要求數量上限,以及要求在佇列中的時間長度。

執行個體大小

與標準環境執行個體相比,彈性環境執行個體可以擁有較高的 CPU 和記憶體上限。因此彈性環境執行個體可以執行需要佔用較多記憶體和 CPU 使用率的應用程式。不過,由於單一執行個體中的執行緒數增加,發生並行錯誤的機率也會提高。

開發人員可以透過 SSH 連線到彈性環境執行個體,並取得執行緒傾印來排解這類問題。

舉例來說,如果您使用 Java 執行階段,可以執行以下指令:

$ ps auwwx | grep java
$ sudo kill -3 
$ sudo docker logs gaeapp

要求逾時上限

雖然標準環境的要求逾時會因所選的調整資源配置類型而異,但彈性環境一律會設為 60 分鐘的逾時。為避免要求開放時間超過 60 分鐘,並可能佔用網路伺服器上的所有執行緒,請採取下列做法:

  • 呼叫外部服務時,請指定逾時值。

  • 實作 Servlet 篩選器,停止耗時過長 (例如 60 秒) 的要求。請確認在篩選器停止要求後,應用程式能否恢復一致狀態。

執行緒管理

Java 8 之前的標準環境 Java 執行階段只能使用使用 App Engine 標準環境 SDK 建立的執行緒。將應用程式從第一代 Java 標準環境執行階段移植至彈性環境的開發人員,必須改用原生執行緒程式庫。如果應用程式需要極大量執行緒,則相較於建立明確的執行緒,使用執行緒集區的執行效率可能較高。

流量遷移

標準環境提供流量遷移功能,可將流量逐步移到新版本,儘可能減少延遲遽增的時間。請參閱流量遷移文件,瞭解將流量切換到新版本時,如何避免延遲時間遽增。

單一區域故障

標準環境應用程式屬於單一位置,這表示應用程式的所有執行個體都位於單一可用區域中。如果該區域故障,應用程式會在相同地區中的不同區域啟動新的執行個體,且負載平衡器會將流量轉送到新的執行個體。由於系統須載入要求及清除 Memcache,因此延遲時間會遽增。

彈性環境應用程式使用地區代管執行個體群組,表示執行個體會分布在單一地區中的多個可用區域。如果單一區域故障,負載平衡器就會停止將流量轉送到該區域。如果您已將自動調度資源設定為儘快執行執行個體,則在自動調度資源建立更多執行個體之前,短時間內會有超載的情況發生。

費用比較

比較在標準環境和彈性環境執行工作負載的費用時,須考量許多因素,其中包括:

  • 每個 MCycle 應支付的費用。
  • CPU 平台功能,這會影響每個 MCycle 可完成的工作。
  • 在每個平台上運行執行個體的優先順序。
  • 部署費用;每個平台的費用可能不盡相同,如果您的應用程式使用持續部署系統,費用可能相當可觀。
  • 執行階段負擔。

您必須多方測試,才能判斷在每個平台上執行工作負載的費用。在彈性環境測試時,您可以將每個核心的 QPS 視為應用程式成本效益的代表,判斷變更是否會影響費用。然而標準環境並不提供這類機制,您的應用程式也就不會有成本效益即時指標,您必須在執行變更後,等候每日計費週期完成才能獲知費用變化。

微服務

標準環境允許使用 X-Appengine-Inbound-Appid 要求標頭在應用程式之間進行安全驗證,而彈性環境不提供這類功能。如要在應用程式之間進行安全驗證,建議您使用 OAuth

部署作業

標準環境中的部署作業通常比彈性環境中的部署作業更快速。在彈性環境中擴充現有版本比部署新版本更快速,因為新版本的網路程式設計通常是彈性環境部署中最費時的環節。如要在彈性環境中快速復原,一種做法是將已知可正常運作的版本縮小為單一執行個體。之後您可以擴充該版本,然後使用流量拆分功能將所有流量轉送到該版本。

使用彈性環境的時機

彈性環境可彌補標準環境的不足之處。如果您已有在標準環境中執行的應用程式,通常不需要將整個應用程式遷移至彈性環境。您只需要找出應用程式中有哪些部分需要更多 CPU、RAM、專用第三方程式庫或程式,或是需要執行在標準環境中無法執行的動作。您識別出應用程式的這些部分之後,請建立使用彈性環境的小型 App Engine 服務來處理這些部分。您在標準環境執行的現有服務可以使用 HTTP、Cloud Tasks 或 Cloud Pub/Sub 呼叫其他服務。

舉例來說,如果您已有在標準環境中執行的網頁應用程式,且想新增功能將檔案轉換為 PDF,可以另外編寫在彈性環境執行的微服務,專門處理 PDF 轉換作業。這項微服務可以是簡易程式,只包含一或兩個要求處理常式,並可安裝及使用任何可用的 Linux 程式 (如 unoconv) 協助轉換作業。

您的主要應用程式仍會保留在標準環境中,並可透過 HTTP 直接呼叫這項微服務;如果您預估轉換作業會耗時很久,應用程式可以使用 Cloud TasksPub/Sub 將要求排入佇列。

後續步驟

將應用程式在標準環境使用的服務對應到彈性環境的類似服務