

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

# Lambda 受管執行個體的 Node.js 執行時間
<a name="lambda-managed-instances-nodejs-runtime"></a>

對於 Node.js 執行期，Lambda 受管執行個體使用具有 `async`/ `await`型執行的工作者執行緒來處理並行請求。每個工作者執行緒會發生一次函數初始化。並行調用由兩個維度處理：工作者執行緒提供跨 vCPUs平行處理，而非同步執行則在每個執行緒內提供並行處理。相同工作者執行緒處理的每個並行請求都會共用相同的處理常式物件和全域狀態，需要在多個並行請求下安全處理。

## 並行上限
<a name="lambda-managed-instances-nodejs-max-concurrency"></a>

Lambda 傳送至每個執行環境的並行請求數目上限是由函數組態中的 `PerExecutionEnvironmentMaxConcurrency`設定所控制。這是選用設定，預設值會根據執行時間而有所不同。對於 Node.js 執行時間，預設值為每個 vCPU 64 個並行請求，或者您可以設定自己的值。Lambda 會根據每個執行環境的容量，自動調整並行請求的數量，直到設定的最大值為止，以吸收這些請求。

對於 Node.js，每個執行環境可以處理的並行請求數量取決於工作者執行緒的數量，以及每個工作者執行緒的非同步處理並行請求的容量。預設的工作者執行緒數量取決於可用的 vCPUs 數量，或者您可以透過設定`AWS_LAMBDA_NODEJS_WORKER_COUNT`環境變數來設定工作者執行緒數量。我們建議您使用非同步函數處理常式，因為這允許處理每個工作者執行緒的多個請求。如果您的函數處理常式是同步的，則每個工作者執行緒一次只能處理單一請求。

## 為多並行建置函數
<a name="lambda-managed-instances-nodejs-building"></a>

使用非同步函數處理常式，每個執行階段工作者會同時處理多個請求。全域物件將在多個並行請求之間共用。對於可變物件，請避免使用全域狀態或使用 `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 回呼型處理常式
<a name="lambda-managed-instances-nodejs-callback-handlers"></a>

使用 Node.js 22 時，您無法搭配 Lambda 受管執行個體使用以回呼為基礎的函數處理常式。只有 Lambda （預設） 函數支援以回呼為基礎的處理常式。對於 Node.js 24 和更新版本的執行時間，Lambda （預設） 和 Lambda 受管執行個體的回呼型函數處理常式都已棄用。

反之，使用 Lambda 受管執行個體時，請使用 `async`函數處理常式。如需詳細資訊，請參閱在 [Node.js 中定義 Lambda 函數處理常式。](https://docs.aws.amazon.com/lambda/latest/dg/nodejs-handler.html)

## 共用 /tmp 目錄
<a name="lambda-managed-instances-nodejs-shared-tmp"></a>

`/tmp` 目錄會跨執行環境中的所有並行請求共用。同時寫入相同檔案可能會導致資料損毀，例如，如果另一個程序覆寫檔案。若要解決此問題，請實作共用檔案的檔案鎖定，或針對每個請求使用唯一的檔案名稱以避免衝突。請記得清除不需要的檔案，以避免耗盡可用空間。

## 日誌
<a name="lambda-managed-instances-nodejs-logging"></a>

日誌交錯 （來自在日誌中交錯之不同請求的日誌項目） 在多並行系統中是正常的。使用 Lambda 受管執行個體的函數一律使用[進階記錄控制](monitoring-logs.md#monitoring-cloudwatchlogs-advanced)所引進的結構化 JSON 日誌格式。此格式包含 `requestId`，允許日誌項目與單一請求相關聯。當您使用`console`記錄器時， `requestId` 會自動包含在每個日誌項目中。如需詳細資訊，請參閱 [搭配 Node.js 使用 Lambda 進階日誌控制項](nodejs-logging.md#node-js-logging-advanced)。

熱門的第三方日誌程式庫，例如 [Winston](https://github.com/winstonjs/winston)，通常包含使用 主控台進行日誌輸出的支援。

## 請求內容
<a name="lambda-managed-instances-nodejs-request-context"></a>

使用 `context.awsRequestId` 可讓您以非同步安全的方式存取目前請求的請求 ID。

使用 `context.xRayTraceId` 存取 X-Ray 追蹤 ID。這可提供目前請求之追蹤 ID 的並行安全存取。Lambda 不支援具有 Lambda 受管執行個體`_X_AMZN_TRACE_ID`的環境變數。使用 AWS SDK 時，會自動傳播 X-Ray 追蹤 ID。

使用 `context.getRemainingTimeInMillis()` 偵測逾時。如需詳細資訊，請參閱[錯誤處理和復原](lambda-managed-instances-execution-environment.md#lambda-managed-instances-error-handling)。

## 初始化和關閉
<a name="lambda-managed-instances-nodejs-init-shutdown"></a>

每個工作者執行緒會發生一次函數初始化。如果您的函數在初始化期間發出日誌，您可能會看到重複的日誌項目。

對於具有擴充功能的 Lambda 函數，執行環境會在關閉期間發出 SIGTERM 訊號。延伸項目使用此訊號來觸發清除任務，例如排清緩衝區。具有擴充功能的 Lambda （預設） 函數也可以使用 訂閱 SIGTERM 訊號`process.on()`。使用 Lambda 受管執行個體的函數不支援此功能，因為 `process.on()`無法與工作者執行緒搭配使用。若要詳細了解執行環境生命週期，請參閱 [了解 Lambda 執行環境生命週期](lambda-runtime-environment.md)。

## 相依性版本
<a name="lambda-managed-instances-nodejs-dependencies"></a>

Lambda 受管執行個體需要下列最低套件版本：
+ AWS 適用於 JavaScript 的 SDK v3：3.933.0 版或更新版本
+ AWS 適用於 Node.js 的 X-Ray 開發套件：3.12.0 版或更新版本
+ AWS Distro for OpenTelemetry - JavaScript 檢測：0.8.0 版或更新版本
+ Powertools for AWS Lambda (TypeScript)：2.29.0 版或更新版本

## Lambda 的 Powertools AWS (TypeScript)
<a name="lambda-managed-instances-nodejs-powertools"></a>

Powertools for AWS Lambda (TypeScript) 與 Lambda 受管執行個體相容，並提供用於記錄、追蹤、指標等的公用程式。如需詳細資訊，請參閱 [Powertools for AWS Lambda (TypeScript)](https://github.com/aws-powertools/powertools-lambda-typescript)。

## 後續步驟
<a name="lambda-managed-instances-nodejs-next-steps"></a>
+ 檢閱 [Lambda 受管執行個體的 Java 執行期](lambda-managed-instances-java-runtime.md)
+ 檢閱 [Lambda 受管執行個體的 Python 執行時間](lambda-managed-instances-python-runtime.md)
+ 檢閱 [Lambda 受管執行個體的 .NET 執行時間](lambda-managed-instances-dotnet-runtime.md)
+ 了解[擴展 Lambda 受管執行個體](lambda-managed-instances-scaling.md)