View a markdown version of this page

執行環境生命週期 - AWS Lambda

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

執行環境生命週期

執行環境是一種隔離的運算執行個體,可執行 HTTP 伺服器。當流量到達時, 會為您的 Lambda Web 函數 AWS Lambda 建立執行環境。它會將請求路由到作用中環境,並移除不再需要的環境。了解此生命週期可協助您最佳化啟動效能,以及正確處理初始化和關機的寫入程式碼。

生命週期階段

每個執行環境都會經過下列階段:

三個執行環境階段:初始化、就緒和關閉。
階段 發生的情況 請求處理
初始化 Lambda 會載入您的程式碼、準備執行時間,並啟動您的 HTTP 伺服器程序。您的伺服器必須在 10 秒AWS_LAMBDA_HTTP_ENDPOINT內開始接聽地址。 環境無法在初始化期間提供請求。
備妥 您的 HTTP 伺服器正在接聽,且環境可用於接收請求。Lambda 會將傳入請求路由到此環境。 環境接受最高maxConcurrencyPerEnvironment限制的請求。
關閉 Lambda 會停止將新請求路由到環境,讓處理中的請求盡最大努力完成、傳送 SIGTERM,然後終止環境。 沒有新請求路由到環境。傳輸中請求可以繼續,但不保證完成。在 之後SIGTERM,程序最多有 1 秒的時間來完成清除。程序狀態遺失。

初始化 (冷啟動)

當 Lambda 建立新的執行環境時,初始化階段會包含下列步驟:

  1. Lambda 會從 .zip 部署套件載入程式碼。

  2. Lambda 會設定執行期環境 (包括 Node.js和您的環境變數)。

  3. Lambda 會啟動您的應用程式程序。

  4. 您的 HTTP 伺服器開始接聽AWS_LAMBDA_HTTP_ENDPOINT環境變數指定的主機和連接埠。它必須在 10 秒內開始接聽。

  5. Lambda 偵測到您的伺服器正在接聽,並將環境標記為就緒。

當 Lambda 必須建立新的環境來處理請求時,就會發生冷啟動,因為沒有可用的環境。冷啟動後的第一個請求會遇到初始化階段的額外延遲。後續對相同環境的請求不會產生此成本。

若要降低冷啟動影響:

  • 將部署套件大小降至最低。較小的套件載入速度更快。

  • 縮短伺服器啟動時間。在伺服器開始接聽後,將繁重初始化 (例如載入大型資料檔案) 延遲到 。Lambda 會在伺服器接聽時立即將請求路由到環境,因此讓依賴延遲工作的請求處理常式等待它完成,例如等待共享承諾。

  • 針對資料庫連線和外部服務用戶端使用延遲初始化。在第一次請求時建立連線,而不是在啟動時建立連線。

縮減規模和關閉

Lambda 會監控端點的環境使用率,並移除不需要的環境,例如流量減少時。在移除環境之前,Lambda 會使用下列關閉順序:

  1. Lambda 會停止將新請求路由到環境。

  2. Lambda 允許盡可能完成處理中的請求。

  3. Lambda 傳送 SIGTERM。在 Lambda 終止並移除環境之前,此程序最多有 1 秒的時間來完成清除。

當沒有流量時,Lambda 會將 Web 函數擴展到零環境。scale-to-zero期間之後的下一個請求會觸發新的冷啟動。

如果您的應用程式需要在關機期間執行清除,請處理 SIGTERM。清除必須在 1 秒內完成。請勿依賴正在執行的關機回呼,因為 Lambda 無法保證在所有失敗模式下正常關機,例如基礎硬體故障。

下列範例處理 SIGTERM:

process.on('SIGTERM', () => { // Finish short cleanup, such as flushing buffered logs, within 1 second. process.exit(0); });

環境重複使用

Lambda 會在多個請求中重複使用執行環境,以避免重複冷啟動。單一環境可以在其生命週期內提供數千個請求。這表示:

  • 全域狀態持續 – 伺服器在啟動時初始化的變數、快取和連線會在請求之間持續存在。您可以使用此功能進行記憶體內快取或連線集區。

  • 檔案系統狀態會持續 – 程式碼寫入本機檔案系統 (例如 /tmp) 的檔案會持續存在,直到 Lambda 移除環境為止。

  • 無保證生命週期 – Lambda 可以隨時移除環境。請勿依賴持續特定期間的環境。將重要資料保留到外部存放區,例如 DynamoDB 或 Amazon S3。

並行請求處理

每個 Web 函數執行環境都會處理多個並行 HTTP 請求。修訂版上的 maxConcurrencyPerEnvironment設定可控制每個環境的同時請求數量上限。

由於您的伺服器會同時處理多個請求,因此您的程式碼必須安全才能同時使用:

  • 請勿在全域變數中存放每個請求狀態。請改用請求範圍變數或中介軟體內容。

  • 保護跨await邊界修改的共用可變狀態,例如快取或計數器。請求在事件迴圈上交錯。如果read-modify-write序列跨越非同步操作,則另一個傳輸中請求可以在序列完成之前讀取或變更狀態。

  • 請注意, Node.js使用單一執行緒事件迴圈。CPU 密集型同步操作會封鎖該環境中的所有並行請求。使用非同步 I/O 並避免封鎖事件迴圈。

如需並行設定和最佳化的詳細資訊,請參閱 Lambda Web 函數的擴展行為。