本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
Lambda 受管執行個體的 Node.js 執行時間
對於 Node.js 執行期,Lambda 受管執行個體使用工作者執行緒搭配 async/ await型執行來處理並行請求。每個工作者執行緒會初始化函數一次。並行調用由兩個維度處理:工作者執行緒提供跨 vCPUs平行處理,而非同步執行則在每個執行緒內提供並行處理。相同工作者執行緒處理的每個並行請求都會共用相同的處理常式物件和全域狀態,需要在多個並行請求下安全處理。
並行上限
Lambda 傳送至每個執行環境的並行請求數目上限是由函數組態中的 PerExecutionEnvironmentMaxConcurrency設定所控制。這是選用設定,預設值會根據執行時間而有所不同。對於 Node.js 執行時間,預設值為每個 vCPU 64 個並行請求,或者您可以設定自己的值。Lambda 會根據每個執行環境的容量,自動調整並行請求的數量,直到設定的最大值為止,以吸收這些請求。
對於 Node.js,每個執行環境可以處理的並行請求數量取決於工作者執行緒的數量,以及每個工作者執行緒的非同步處理並行請求的容量。預設的工作者執行緒數量取決於可用的 vCPUs 數量,或者您可以透過設定AWS_LAMBDA_NODEJS_WORKER_COUNT環境變數來設定工作者執行緒數量。我們建議您使用非同步函數處理常式,因為這允許處理每個工作者執行緒的多個請求。如果您的函數處理常式是同步的,則每個工作者執行緒一次只能處理單一請求。
為多並行建置函數
使用非同步函數處理常式,每個執行階段工作者會同時處理多個請求。全域物件將在多個並行請求之間共用。對於可變物件,請避免使用全域狀態或使用 AsyncLocalStorage。
AWS SDK 用戶端是非同步安全的,不需要特殊處理。
範例:全域狀態
下列程式碼使用在函數處理常式內變動的全域物件。這不是非同步安全。
let state = { currentUser: null, requestData: null }; export const handler = async (event, context) => { state.currentUser = event.userId; state.requestData = event.data; await processData(state.requestData); // state.currentUser might now belong to a different request return { user: state.currentUser }; };
在函數處理常式內初始化state物件可避免共用全域狀態。
export const handler = async (event, context) => { let state = { currentUser: event.userId, requestData: event.data }; await processData(state.requestData); return { user: state.currentUser }; };
範例:資料庫連線
下列程式碼使用在多個調用之間共用的共用用戶端物件。視使用的連線程式庫而定,這可能不是並行安全。
const { Client } = require('pg'); // Single connection created at init time const client = new Client({ host: process.env.DB_HOST, database: process.env.DB_NAME, user: process.env.DB_USER, password: process.env.DB_PASSWORD }); // Connect once during cold start client.connect(); exports.handler = async (event) => { // Multiple parallel invocations share this single connection = BAD // With multi-concurrent Lambda, queries will collide const result = await client.query('SELECT * FROM users WHERE id = $1', [event.userId]); return { statusCode: 200, body: JSON.stringify(result.rows[0]) }; };
並行安全方法是使用連線集區。集區會針對每個並行資料庫查詢使用個別的連線。
const { Pool } = require('pg'); // Connection pool created at init time const pool = new Pool({ host: process.env.DB_HOST, database: process.env.DB_NAME, user: process.env.DB_USER, password: process.env.DB_PASSWORD, max: 20, // Max connections in pool idleTimeoutMillis: 30000, connectionTimeoutMillis: 2000 }); exports.handler = async (event) => { // Pool gives each parallel invocation its own connection const result = await pool.query('SELECT * FROM users WHERE id = $1', [event.userId]); return { statusCode: 200, body: JSON.stringify(result.rows[0]) }; };
Node.js 22 回呼型處理常式
使用 Node.js 22 時,您無法搭配 Lambda 受管執行個體使用以回呼為基礎的函數處理常式。只有 Lambda (預設) 函數支援以回呼為基礎的處理常式。對於 Node.js 24 和更新版本的執行時間,Lambda (預設) 和 Lambda 受管執行個體的回呼型函數處理常式都會被取代。
反之,使用 Lambda 受管執行個體時請使用 async函數處理常式。如需詳細資訊,請參閱在 Node.js 中定義 Lambda 函數處理常式。
共用 /tmp 目錄
/tmp 目錄會在執行環境中所有並行請求之間共用。同時寫入相同檔案可能會導致資料損毀,例如,如果另一個程序覆寫檔案。若要解決此問題,請實作共用檔案的檔案鎖定,或針對每個請求使用唯一的檔案名稱以避免衝突。請記得清除不需要的檔案,以避免耗盡可用空間。
日誌
日誌交錯 (來自在日誌中交錯之不同請求的日誌項目) 在多並行系統中是正常的。使用 Lambda 受管執行個體的函數一律使用進階記錄控制所引進的結構化 JSON 日誌格式。此格式包含 requestId,允許日誌項目與單一請求相關聯。當您使用console記錄器時, requestId 會自動包含在每個日誌項目中。如需詳細資訊,請參閱搭配使用 Lambda 進階記錄控制與 Node.js。
熱門的第三方日誌程式庫,例如 Winston
請求內容
使用 context.awsRequestId 可讓您以非同步安全的方式存取目前請求的請求 ID。
使用 context.xRayTraceId 存取 X-Ray 追蹤 ID。這可讓您同時安全存取目前請求的追蹤 ID。Lambda 不支援具有 Lambda 受管執行個體_X_AMZN_TRACE_ID的環境變數。使用 AWS SDK 時,會自動傳播 X-Ray 追蹤 ID。
初始化和關閉
每個工作者執行緒會初始化函數一次。如果您的函數在初始化期間發出日誌,您可能會看到重複的日誌項目。
對於具有擴充功能的 Lambda 函數,執行環境會在關閉期間發出 SIGTERM 訊號。延伸項目使用此訊號來觸發清除任務,例如排清緩衝區。具有擴充功能的 Lambda (預設) 函數也可以使用 訂閱 SIGTERM 訊號process.on()。使用 Lambda 受管執行個體的函數不支援此功能,因為 process.on()無法與工作者執行緒搭配使用。若要進一步了解執行環境生命週期,請參閱了解 Lambda 執行環境生命週期。
相依性版本
Lambda 受管執行個體需要下列最低套件版本:
-
AWS 適用於 JavaScript 的 SDK v3:3.933.0 版或更新版本
-
AWS 適用於 Node.js 的 X-Ray 開發套件:3.12.0 版或更新版本
-
AWS Distro for OpenTelemetry - JavaScript 檢測:0.8.0 版或更新版本
-
適用於 AWS Lambda 的 Powertools (TypeScript):2.29.0 版或更新版本
Lambda 的 Powertools AWS (TypeScript)
Powertools for AWS Lambda (TypeScript) 與 Lambda 受管執行個體相容,並提供用於記錄、追蹤、指標等的公用程式。如需詳細資訊,請參閱 Powertools for AWS Lambda (TypeScript)