

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

# Lambda 受管執行個體執行時間
<a name="lambda-managed-instances-runtimes"></a>

使用 Lambda 受管執行個體時，Lambda 會以不同的方式處理請求。Lambda 受管執行個體不會在每個執行環境中依序處理請求，而是在每個執行環境中同時處理多個請求。此執行模型變更表示使用 Lambda 受管執行個體的函數需要考慮執行緒安全性、狀態管理和內容隔離，這些問題不會出現在 Lambda （預設） 單一並行模型中。此外，多並行實作會因執行時間而有所不同。

## 支援的語言
<a name="lambda-managed-instances-supported-runtimes"></a>

Lambda 受管執行個體可與下列程式設計語言和執行時間搭配使用：
+ **Java：**Java 21 和更新版本。
+ **Python：**Python 3.13 和更新版本。
+ **Node.js：**Node.js 22 和更新版本。
+ **.NET：**.NET 8 及更新版本。
+ **Rust：**支援使用僅限作業系統的執行時間 `provided.al2023`和更新版本。

## 語言特定考量事項
<a name="lambda-managed-instances-runtime-considerations"></a>

每種程式設計語言都會以不同的方式實作多並行。您需要了解如何在您選擇的程式設計語言中實作多並行，以套用適當的並行最佳實務。

**Java**

使用單一程序搭配並行的作業系統執行緒。多個執行緒同時執行處理常式方法，需要安全處理狀態和共用資源的執行緒。

**Python**

使用多個 Python 程序，其中每個並行請求在個別程序中執行。這可避免大多數並行問題，但 `/tmp`目錄等共用資源需要小心。

**Node.js**

使用具有非同步執行的[工作者執行緒](https://nodejs.org/api/worker_threads.html)。並行請求會分散到工作者執行緒，而且每個工作者執行緒也可以非同步處理並行請求，需要安全處理狀態和共用資源。

**.NET**

使用 .NET 任務來非同步處理多個並行請求。需要安全處理狀態和共用資源。

**Rust**

使用單一程序搭配由 [Tokio](https://tokio.rs/) 提供支援的非同步任務。處理常式必須是 `Clone` \$1 `Send`。

## 後續步驟
<a name="lambda-managed-instances-runtime-next-steps"></a>

如需每個執行時間的詳細資訊，請參閱下列主題：
+ [Lambda 受管執行個體的 Java 執行期](lambda-managed-instances-java-runtime.md)
+ [Lambda 受管執行個體的 Node.js 執行時間](lambda-managed-instances-nodejs-runtime.md)
+ [Lambda 受管執行個體的 Python 執行期](lambda-managed-instances-python-runtime.md)
+ [Lambda 受管執行個體的 .NET 執行時間](lambda-managed-instances-dotnet-runtime.md)
+ [Rust 支援 Lambda 受管執行個體](lambda-managed-instances-rust.md)

# Lambda 受管執行個體的 Java 執行期
<a name="lambda-managed-instances-java-runtime"></a>

對於 Java 執行期，Lambda 受管執行個體會使用作業系統執行緒來並行。Lambda 會在初始化期間為每個執行環境載入您的處理常式物件一次，然後建立多個執行緒。這些執行緒會平行執行，並且需要安全處理狀態和共用資源的執行緒。每個執行緒共用相同的處理常式物件和任何靜態欄位。

## 並行組態
<a name="lambda-managed-instances-java-concurrency-config"></a>

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

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

使用 Lambda 受管執行個體時，您應該套用與任何其他多執行緒環境中相同的執行緒安全實務。由於處理常式物件會跨所有執行時間工作者執行緒共用，因此任何變動狀態都必須是執行緒安全。這包括集合、資料庫連線，以及在請求處理期間修改的任何靜態物件。

AWS SDK 用戶端是安全的執行緒，不需要特殊處理。

**範例：資料庫連線集區**

下列程式碼使用在執行緒之間共用的靜態資料庫連線物件。視使用的連線程式庫而定，這可能不安全執行緒。

```
public class DBQueryHandler implements RequestHandler<Object, String> {
    // Single connection shared across all threads - NOT SAFE
    private static Connection connection;

    public DBQueryHandler() {
        this.connection = DriverManager.getConnection(jdbcUrl, username, password);
    }

    @Override
    public String handleRequest(Object input, Context context) {
        PreparedStatement stmt = connection.prepareStatement(query);
        ResultSet rs = stmt.executeQuery();
        // Multiple threads using same connection causes issues
        return result.toString();
    }
}
```

安全執行緒的方法是使用連線集區。在下列範例中，函數處理常式會從集區擷取連線。連線僅用於單一請求的內容。

```
public class DBQueryHandler implements RequestHandler<Object, String> {

    private static HikariDataSource dataSource;

    public DBQueryHandler() {
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl("jdbc:mysql://localhost:3306/your_database");
        dataSource = new HikariDataSource(config); // Create pool once per Lambda container
    }

    @Override
    public String handleRequest(Object input, Context context) {
        String query = "SELECT column_name FROM your_table LIMIT 10";
        StringBuilder result = new StringBuilder("Data:\n");

        // try-with-resources automatically calls close() on the connection,
        // which returns it to the HikariCP pool (does NOT close the physical DB connection)
        try (Connection connection = dataSource.getConnection();
             PreparedStatement stmt = connection.prepareStatement(query);
             ResultSet rs = stmt.executeQuery()) {

            while (rs.next()) {
                result.append(rs.getString("column_name")).append("\n");
            }

        } catch (Exception e) {
            context.getLogger().log("Error: " + e.getMessage());
            return "Error";
        }

        return result.toString();
    }
}
```

**範例：集合**

標準 Java 集合不安全執行緒：

```
public class Handler implements RequestHandler<Object, String> {
    private static List<String> items = new ArrayList<>();
    private static Map<String, Object> cache = new HashMap<>();

    @Override
    public String handleRequest(Object input, Context context) {
        items.add("list item");  // Not thread-safe
        cache.put("key", input); // Not thread-safe
        return "Success";
    }
}
```

請改用安全執行緒集合：

```
public class Handler implements RequestHandler<Object, String> {
    private static final List<String> items = 
        Collections.synchronizedList(new ArrayList<>());
    private static final ConcurrentHashMap<String, Object> cache = 
        new ConcurrentHashMap<>();

    @Override
    public String handleRequest(Object input, Context context) {
        items.add("list item");  // Thread-safe
        cache.put("key", input); // Thread-safe
        return "Success";
    }
}
```

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

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

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

日誌交錯 （來自在日誌中交錯之不同請求的日誌項目） 在多並行系統中是正常的。

使用 Lambda 受管執行個體的函數一律使用[進階記錄控制](monitoring-logs.md#monitoring-cloudwatchlogs-advanced)所引進的結構化 JSON 日誌格式。此格式包含 `requestId`，允許日誌項目與單一請求相關聯。當您使用來自 `context.getLogger()` 的`LambdaLogger`物件`requestId`時， 會自動包含在每個日誌項目中。如需詳細資訊，請參閱 [搭配 Java 使用 Lambda 進階日誌控制項](java-logging.md#java-logging-advanced)。

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

`context` 物件繫結至請求執行緒。使用 `context.getAwsRequestId()`可安全執行緒存取目前請求的請求 ID。

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

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

如果您在程式中使用虛擬執行緒或在初始化期間建立執行緒，您將需要將任何必要的請求內容傳遞至這些執行緒。

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

每個執行環境會發生一次函數初始化。在初始化期間建立的物件會跨執行緒共用。

對於具有擴充功能的 Lambda 函數，執行環境會在關閉期間發出 SIGTERM 訊號。延伸項目使用此訊號來觸發清除任務，例如排清緩衝區。您可以訂閱 SIGTERM 事件來觸發函數清除任務，例如關閉資料庫連線。若要詳細了解執行環境生命週期，請參閱 [了解 Lambda 執行環境生命週期](lambda-runtime-environment.md)。

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

Lambda 受管執行個體需要下列最低套件版本：
+ AWS 適用於 Java 的 SDK 2.0：2.34.0 版或更新版本
+ AWS 適用於 Java 的 X-Ray 開發套件：2.20.0 版或更新版本
+ AWS Distro for OpenTelemetry - 適用於 Java 的檢測：2.20.0 版或更新版本
+ 適用於 AWS Lambda (Java) 的 Powertools：2.8.0 版或更新版本

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

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

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

# 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)

# Lambda 受管執行個體的 Python 執行期
<a name="lambda-managed-instances-python-runtime"></a>

Lambda 執行時間使用多個 Python 程序來處理並行請求。每個並行請求會在單獨的程序中執行，具有自己的記憶體空間和初始化。每個程序一次可同步處理一個請求。程序不會直接共用記憶體，因此全域變數、模組層級快取和單頓物件會在並行請求之間隔離。

## 並行組態
<a name="lambda-managed-instances-python-concurrency-config"></a>

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

**重要**  
使用程序型並行表示每個執行階段工作者程序都會執行自己的初始化。總記憶體用量等於每個程序的記憶體乘以並行程序的數量。如果您要載入大型程式庫或資料集並具有高並行性，則記憶體使用量會很大。根據您的工作負載，您可能需要調整 CPU-to-memory的比率，或使用較低的並行設定，以避免超過可用的記憶體。您可以使用 CloudWatch 中的 `MemoryUtilization` 指標來追蹤記憶體耗用量。

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

由於程序型多並行模型，使用 Python 執行時間的 Lambda 受管執行個體函數不會同時從多個調用存取記憶體內資源。您不需要為記憶體內並行安全性套用編碼實務。

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

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

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

日誌交錯 （來自在日誌中交錯之不同請求的日誌項目） 在多並行系統中是正常的。

使用 Lambda 受管執行個體的函數一律使用[進階記錄控制](monitoring-logs.md#monitoring-cloudwatchlogs-advanced)所引進的結構化 JSON 日誌格式。此格式包含 `requestId`，允許日誌項目與單一請求相關聯。當您從 Lambda 中的 Python 標準程式庫使用`logging`模組時， `requestId` 會自動包含在每個日誌項目中。如需詳細資訊，請參閱[搭配 Python 使用 Lambda 進階記錄控制](https://docs.aws.amazon.com/lambda/latest/dg/python-logging.html#python-logging-advanced)。

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

使用 `context.aws_request_id` 存取目前請求的請求 ID。

透過 Python 執行時間，您可以使用 `_X_AMZN_TRACE_ID`環境變數來存取具有 Lambda 受管執行個體的 X-Ray 追蹤 ID。使用 AWS SDK 時，會自動傳播 X-Ray 追蹤 ID。

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

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

每個程序會初始化一次函數。如果您的函數在初始化期間發出日誌，您可能會看到重複的日誌項目。

對於具有擴充功能的 Lambda 函數，執行環境會在關閉期間發出 SIGTERM 訊號。延伸項目使用此訊號來觸發清除任務，例如排清緩衝區。您可以訂閱 SIGTERM 事件來觸發函數清除任務，例如關閉資料庫連線。若要詳細了解執行環境生命週期，請參閱 [了解 Lambda 執行環境生命週期](lambda-runtime-environment.md)。

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

Lambda 受管執行個體需要下列最低套件版本：
+ 適用於 AWS Lambda (Python) 的 Powertools：3.23.0 版或更新版本

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

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

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

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

對於 .NET 執行時間，Lambda 受管執行個體在每個執行環境中使用單一 .NET 程序。使用 .NET 任務處理多個並行請求。

## 並行組態
<a name="lambda-managed-instances-dotnet-concurrency-config"></a>

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

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

使用 Lambda 受管執行個體時，您應該套用與任何其他多並行環境中相同的並行安全實務。由於處理常式物件會跨所有任務共用，因此任何變動狀態都必須是執行緒安全。這包括集合、資料庫連線，以及在請求處理期間修改的任何靜態物件。

AWS SDK 用戶端可安全執行緒，不需要特殊處理。

**範例：資料庫連線集區**

下列程式碼使用在並行請求之間共用的靜態資料庫連線物件。`SqlConnection` 物件執行緒不安全。

```
public class DBQueryHandler
{
    // Single connection shared across threads - NOT SAFE
    private SqlConnection connection;

    public DBQueryHandler()
    {
        connection = new SqlConnection("your-connection-string-here");
        connection.Open();
    }

    public string Handle(object input, ILambdaContext context)
    {
        using var cmd = connection.CreateCommand();
        cmd.CommandText = "SELECT ..."; // your query

        using var reader = cmd.ExecuteReader();

        ...
    }
}
```

若要解決此問題，請針對從連線集區繪製的每個請求使用個別的連線。ADO.NET 等供應商會在連線物件開啟時`Microsoft.Data.SqlClient`自動支援連線集區。

```
public class DBQueryHandler
{
    public DBQueryHandler()
    {
    }

    public string Handle(object input, ILambdaContext context)
    {
        using var connection = new SqlConnection("your-connection-string-here");
        connection.Open();
        using var cmd = connection.CreateCommand();
        cmd.CommandText = "SELECT ..."; // your query

        using var reader = cmd.ExecuteReader();

        ...
    }
}
```

**範例：集合**

標準 .NET 集合不安全執行緒：

```
public class Handler
{
    private static List<string> items = new List<string>();
    private static Dictionary<string, object> cache = new Dictionary<string, object>();

    public string FunctionHandler(object input, ILambdaContext context)
    {
        items.Add(context.AwsRequestId);
        cache["key"] = input;

        return "Success";
    }
}
```

使用 `System.Collections.Concurrent`命名空間的集合以確保並行安全：

```
public class Handler
{
    private static ConcurrentBag<string> items = new ConcurrentBag<string>();
    private static ConcurrentDictionary<string, object> cache = new ConcurrentDictionary<string, object>();

    public string FunctionHandler(object input, ILambdaContext context)
    {
        items.Add(context.AwsRequestId);
        cache["key"] = input;

        return "Success";
    }
}
```

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

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

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

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

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

使用 `context.AwsRequestId` 屬性來存取目前請求的請求 ID。

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

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

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

每個執行環境都會初始化一次函數。在初始化期間建立的物件會跨請求共用。

對於具有擴充功能的 Lambda 函數，執行環境會在關閉期間發出 SIGTERM 訊號。延伸項目使用此訊號來觸發清除任務，例如排清緩衝區。您可以訂閱 SIGTERM 事件來觸發函數清除任務，例如關閉資料庫連線。若要詳細了解執行環境生命週期，請參閱 [了解 Lambda 執行環境生命週期](lambda-runtime-environment.md)。

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

Lambda 受管執行個體需要下列最低套件版本：
+ Amazon.Lambda.Core：2.7.1 版或更新版本
+ Amazon.Lambda.RuntimeSupport：1.14.1 版或更新版本
+ OpenTelemetry.Instrumentation.AWSLambda:1.14.0 版或更新版本
+ AWSXRayRecorder.Core:2.16.0 版或更新版本
+ AWSSDK.Core：4.0.0.32 版或更新版本

## 適用於 AWS Lambda 的 Powertools (.NET)
<a name="lambda-managed-instances-dotnet-powertools"></a>

[Powertools for AWS Lambda (.NET)](https://docs.aws.amazon.com/powertools/dotnet/) 和 [AWS Distro for OpenTelemetry - Instrumentation for DotNet](https://github.com/aws-observability/aws-otel-dotnet-instrumentation) 目前不支援 Lambda 受管執行個體。

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

# Rust 支援 Lambda 受管執行個體
<a name="lambda-managed-instances-rust"></a>

## 並行組態
<a name="lambda-managed-instances-rust-concurrency-config"></a>

Lambda 傳送至每個執行環境的並行請求數目上限是由函數組態中的 `PerExecutionEnvironmentMaxConcurrency`設定所控制。這是選用設定，而 Rust 的預設值為每個 vCPU 8 個並行請求，或者您可以設定自己的值。此值會決定執行時間產生的 Tokio 任務數量，並在執行環境的生命週期內為靜態。每個工作者一次只處理一個傳輸中請求，每個工作者都沒有多工。Lambda 會根據每個執行環境的容量，自動調整並行請求的數量，直到設定的最大值為止，以吸收這些請求。

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

使用 Lambda 受管執行個體時，您應該套用與任何其他多執行緒環境中相同的執行緒安全實務。由於處理常式物件會跨所有工作者執行緒共用，因此任何變動狀態都必須是執行緒安全。這包括集合、資料庫連線，以及在請求處理期間修改的任何靜態物件。

若要啟用並行請求處理，請將`concurrency-tokio`功能旗標新增至 `Cargo.toml` 檔案。

```
[dependencies]  
lambda_runtime = { version = "1", features = ["concurrency-tokio"] }
```

`lambda_runtime::run_concurrent(…)` 進入點必須在 Tokio 執行時間內從 呼叫，通常由主要函數上的 `#[tokio::main]` 屬性提供。您的處理常式關閉必須實作 [https://doc.rust-lang.org/std/clone/trait.Clone.html](https://doc.rust-lang.org/std/clone/trait.Clone.html) \$1 [https://doc.rust-lang.org/std/marker/trait.Send.html](https://doc.rust-lang.org/std/marker/trait.Send.html)。這可讓架構安全地跨多個非同步任務共用您的處理常式。如果不符合這些邊界，您的程式碼將無法編譯。

當您需要跨調用 （資料庫集區、組態結構） 的共用狀態時，請將它包裝在 中，[https://doc.rust-lang.org/std/sync/struct.Arc.html](https://doc.rust-lang.org/std/sync/struct.Arc.html)並將 `Arc` 複製到每個調用中。

所有適用於 Rust 的 AWS SDK 用戶端都具有並行安全性，不需要特殊處理。

### 範例： AWS SDK 用戶端
<a name="lambda-managed-instances-rust-example-sdk"></a>

下列範例使用 S3 用戶端在每次叫用時上傳物件。在沒有 的情況下，用戶端會直接複製到關閉中`Arc`：

```
let config = aws_config::load_defaults(BehaviorVersion::latest()).await;  
let s3_client = aws_sdk_s3::Client::new(&config);  
  
run_concurrent(service_fn(move |event: LambdaEvent<Request>| {  
    let s3_client = s3_client.clone(); // cheap clone, no Arc needed  
    async move {  
        s3_client.put_object()  
            .bucket(&event.payload.bucket)  
            .key(&event.payload.key)  
            .body(event.payload.body.into_bytes().into())  
            .send()  
            .await?;  
        Ok(Response { message: "uploaded".into() })  
    }  
}))  
.await
```

### 範例：資料庫連線集區
<a name="lambda-managed-instances-rust-example-db"></a>

當您的處理常式需要存取共用狀態，例如用戶端和組態時，請將它包裝在 中，[https://doc.rust-lang.org/std/sync/struct.Arc.html](https://doc.rust-lang.org/std/sync/struct.Arc.html)並將 `Arc` 複製到每個調用中：

```
#[derive(Debug)]  
struct AppState {  
    dynamodb_client: DynamoDbClient,  
    table_name: String,  
    cache_ttl: Duration,  
}  
  
let config = aws_config::load_defaults(BehaviorVersion::latest()).await;  
let state = Arc::new(AppState {  
    dynamodb_client: DynamoDbClient::new(&config),  
    table_name: std::env::var("TABLE_NAME").expect("TABLE_NAME must be set"),  
    cache_ttl: Duration::from_secs(300),  
});  
  
run_concurrent(service_fn(move |event: LambdaEvent<Request>| {  
    let state = state.clone();  
    async move { handle(event, state).await }  
}))  
.await
```

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

`/tmp` 目錄會在相同執行環境中的所有並行調用之間共用。每次叫用使用唯一的檔案名稱 （例如包含請求 ID) 或實作明確檔案鎖定以避免資料損毀。

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

日誌交錯 （來自在日誌中交錯之不同請求的日誌項目） 在多並行系統中是正常的。使用 Lambda 受管執行個體的函數透過 Lambda 的[進階記錄控制](monitoring-logs.md#monitoring-cloudwatchlogs-advanced)支援結構化 JSON 日誌格式。此格式包含 `requestId`，允許日誌項目與單一請求相關聯。如需詳細資訊，請參閱 [實作帶有追蹤套件的進階日誌記錄](rust-logging.md#rust-logging-tracing)。

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

`Context` 物件會直接傳遞至每個處理常式調用。使用 `event.context.request_id` 存取目前請求的請求 ID。

使用 `event.context.xray_trace_id` 存取 X-Ray 追蹤 ID。Lambda 不支援具有 Lambda 受管執行個體`_X_AMZN_TRACE_ID`的環境變數。使用適用於 Rust 的 AWS SDK 時，會自動傳播 X-Ray 追蹤 ID。

使用 `event.context.deadline` 來偵測逾時 — 它包含以毫秒為單位的調用截止日期。

## 初始化和關閉
<a name="lambda-managed-instances-rust-lifecycle"></a>

每個執行環境會發生一次函數初始化。在初始化期間建立的物件會跨請求共用。

對於具有擴充功能的 Lambda 函數，執行環境會在關閉期間發出 SIGTERM 訊號。延伸項目使用此訊號來觸發清除任務，例如排清緩衝區。 `lambda_runtime`提供協助程式，以簡化設定正常的關閉訊號處理[https://docs.rs/lambda_runtime/latest/lambda_runtime/fn.spawn_graceful_shutdown_handler.html](https://docs.rs/lambda_runtime/latest/lambda_runtime/fn.spawn_graceful_shutdown_handler.html)。若要詳細了解執行環境生命週期，請參閱 [了解 Lambda 執行環境生命週期](lambda-runtime-environment.md)。

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

Lambda 受管執行個體需要下列最低套件版本：
+ `lambda_runtime`：1.1.1 版或更新版本，並啟用 `concurrency-tokio`功能
+ 支援的 Rust 版本 (MSRV) 下限為 1.84.0。