

# Lambda 托管实例
<a name="lambda-managed-instances"></a>

Lambda 托管实例让您能够在当前代的 Amazon EC2 实例（包括 Graviton4、网络优化型实例以及其他专用计算选项）上运行 Lambda 函数，而无需管理实例生命周期、操作系统和语言运行时补丁修复、路由、负载均衡或扩展策略。使用 Lambda 托管实例，您可以受益于 EC2 的定价优势，包括 EC2 节省计划和预留实例。

要查看支持的实例类型列表，请前往 [AWS Lambda 定价](https://aws.amazon.com/lambda/pricing/#:~:text=EPU%20pricing%20applies.-,Management%20Fees,-Pricing%20Example%3A%20High)页面并选择您的 AWS 区域。

## 关键功能
<a name="lambda-managed-instances-key-capabilities"></a>

Lambda 托管实例提供以下功能：
+ **选择合适的实例**：根据性能和成本要求（包括对最新 CPU（如 Graviton4）的访问权限、可配置的内存 CPU 比和高带宽网络）选择[合适的实例](https://aws.amazon.com/lambda/pricing/#:~:text=EPU%20pricing%20applies.-,Management%20Fees,-Pricing%20Example%3A%20High)。
+ **自动预置**：AWS 自动预置合适的实例并启动函数执行环境。
+ **动态扩展**：实例根据您的函数流量模式动态扩展。
+ **完全托管的体验**：AWS 负责处理基础设施管理、扩展、补丁修复和路由，同时具备您熟悉的广泛事件源集成功能。

## 何时使用 Lambda 托管实例
<a name="lambda-managed-instances-when-to-use"></a>

对于以下使用案例，可以考虑使用 Lambda 托管实例：
+ **高容量可预测工作负载**：非常适合没有意外流量峰值的稳定状态工作负载。默认情况下，Lambda 托管实例可扩展以处理五分钟内流量翻倍的情况。
+ **性能关键型应用程序**：可以访问最新的 CPU、不同的内存 CPU 比和高网络吞吐量
+ **监管要求**：精细治理需求，以及对 VPC 和实例置放的控制
+ **各种应用程序**：事件驱动型应用程序、媒体/数据处理、Web 应用程序以及迁移到无服务器架构的遗留工作负载

## 工作原理
<a name="lambda-managed-instances-how-it-works"></a>

Lambda 托管实例使用容量提供程序作为运行函数的基础：

1. **创建容量提供程序**：通过指定 VPC 配置以及可选的实例要求和扩展配置来定义函数的运行位置

1. **创建您的函数**：照常创建 Lambda 函数并将其附加到容量提供程序

1. **发布函数版本**：一旦发布，函数版本就会在容量提供程序实例上处于活动状态

当您使用容量提供程序发布函数版本时，Lambda 会在您的账户中启动托管实例。默认情况下，它会启动三个实例以实现可用区的容错功能，并在将您的函数版本标记为 ACTIVE 之前启动三个执行环境。如果您将一个函数附加到一个已运行其他函数的现有容量提供程序上，而此时可用的实例已经具备容纳新函数执行环境所需的容量，则 Lambda 可能不会启动新的实例。

## 并发模式
<a name="lambda-managed-instances-concurrency-model"></a>

Lambda 托管实例支持多并发调用，即一个执行环境能够同时处理多个调用请求。这与 Lambda（默认）计算类型不同，后者采用的是单一并发模型，即一个执行环境每次最多只能运行一个调用。多并发操作能够更有效地利用您的底层 EC2 实例，对于像 Web 服务或批处理作业这类 I/O 密集型应用程序尤其有益。这种执行模式的更改意味着，必须根据运行时的不同对线程安全性、状态管理以及上下文隔离进行不同的处理。

## 租赁和隔离
<a name="lambda-managed-instances-tenancy-isolation"></a>

Lambda（默认）计算类型为多租户类型，它利用 Firecracker microVM 技术来实现运行在共享 Lambda 实例集上的执行环境之间的隔离。Lambda 托管实例在您的账户中运行，以提供最新的 EC2 硬件和定价选项。托管实例使用运行在 EC2 Nitro 实例上的容器来提供隔离，而不是 Firecracker。容量提供程序充当 Lambda 函数的安全边界。函数在实例内的容器中执行。

### 了解托管实例
<a name="lambda-managed-instances-understanding"></a>

Lambda 托管实例函数在您的账户中的 EC2 托管型实例上运行。这些实例由 Lambda 完全托管，这意味着与标准 EC2 实例相比，您对它们的权限有限。您可以通过以下方式识别账户中的 Lambda 托管实例：
+ EC2 `DescribeInstances` 输出中存在 `Operator` 字段
+ 实例上的 `aws:lambda:capacity-provider` 标签

您不能直接在这些实例上执行标准的 EC2 操作，例如手动终止它们。要销毁托管实例，请删除关联的容量提供程序。然后，作为容量提供程序删除过程的一部分，Lambda 将终止实例。

## 定价
<a name="lambda-managed-instances-pricing"></a>

Lambda 托管实例采用基于 EC2 的定价模式，除了 EC2 实例成本外，还将收取 15% 的管理费用。此定价模式支持 EC2 节省计划、预留实例以及适用于您的 EC2 使用量的任何其他定价折扣。有关更多详情，请参阅定价页面：[https://aws.amazon.com/lambda/pricing/](https://aws.amazon.com/lambda/pricing/)

**重要提示：**EC2 定价折扣仅适用于底层 EC2 计算费用，不适用于管理费。

## Lambda 托管实例与 Lambda（默认）计算类型有何不同
<a name="lambda-managed-instances-comparison"></a>

与 Lambda（默认）相比，Lambda 托管实例改变了 Lambda 处理请求的方式。

**主要区别：**


|  | Lambda（默认） | Lambda 托管实例 | 
| --- | --- | --- | 
| 并发模式 | 单并发模型，其中一个执行环境一次最多能支持一个调用。 | 多并发调用，其中一个执行环境可以同时处理多个调用，这样尤其能够提高 IO 密集型应用程序的吞吐量 | 
| 租赁和隔离 | 多租户类型利用 Firecracker microVM 技术实现运行在共享 Lambda 实例集上的执行环境之间的隔离 | 在您的账户中运行，以使用 EC2 Nitro 提供隔离。容量提供程序充当安全边界，且函数在实例内的容器中执行 | 
| 定价模式 | 按请求持续时间定价 | 基于实例的定价，采用 EC2 定价模型，包括按需型实例和预留实例，以及计算类节省计划等节省选项 | 
| 扩展行为 | 当没有可用的执行环境来处理传入的调用时（冷启动）进行扩展。在没有流量的情况下可扩缩至零 | 仅基于 CPU 资源利用率进行异步扩展，无需冷启动。在没有流量的情况下扩缩至配置的最小执行环境数 | 
| 最适合 | 具有突发流量且能够承受一定冷启动时间的函数，或者负载不持续且能从扩缩至零中获益的应用程序。 | 当您想获得 EC2 的灵活性、定价计划和硬件选项时，适用于高容量可预测流量的函数 | 

## 后续步骤
<a name="lambda-managed-instances-next-steps"></a>
+ 了解 [Lambda 托管实例的容量提供程序](lambda-managed-instances-capacity-providers.md)
+ 了解 [Lambda 托管实例的扩展](lambda-managed-instances-scaling.md)
+ 查看 [Java](lambda-managed-instances-java-runtime.md)、[Node.js](lambda-managed-instances-nodejs-runtime.md) 和 [Python](lambda-managed-instances-python-runtime.md) 的运行时特定指南
+ [为您的容量提供程序配置 VPC 连接](lambda-managed-instances-networking.md)
+ 了解 [Lambda 托管实例的安全和权限](lambda-managed-instances-security.md)

# Lambda 托管实例入门
<a name="lambda-managed-instances-getting-started"></a>

## 创建 Lambda 托管实例函数（控制台）
<a name="lambda-managed-instances-getting-started-console"></a>

您可以使用 Lambda 控制台创建一个将在由容量提供程序管理的 Amazon EC2 实例上运行的托管实例函数。

**重要提示：**在创建托管实例函数之前，您必须先创建容量提供程序。这些函数需要容量提供程序来定义运行您的函数的 Amazon EC2 基础设施。

**要创建 Lambda 托管实例函数（控制台）**

1. 打开 Lambda 控制台。

1. 从左侧导航窗格中选择**容量提供程序**。

1. 选择**创建容量提供程序**。

1. 在**容量提供程序设置**部分，为容量提供程序输入一个名称。

1. 为您的容量提供程序选择 VPC 和权限。您可以使用现有角色，也可以创建新的角色。有关创建所需操作员角色的信息，请参阅 [Lambda 托管实例的 Lambda 操作员角色](lambda-managed-instances-operator-role.md)。

1. 展开 **Advanced settings**（高级设置）。

1. 通过选择处理器架构和实例类型来定义您的**实例要求**。

1. 在**自动扩缩**下，为您的容量提供程序指定 EC2 vCPU 的最大数量。您也可以选择**手动实例扩展模式**来设置自己的扩展值以实现精确控制。

1. 选择**创建容量提供程序**以创建新的容量提供程序。

1. 接下来，选择**创建函数**。

1. 选择**从头开始编写**。

1. 在**基本信息**窗格中，提供**函数名称**。

1. 在**运行时**中，选择任何支持的 Lambda 运行时。

1. 为您的函数选择**架构**（与您为容量提供程序选择的架构相同）。默认情况下，为 **x86\$164**。

1. 在**权限**下，确保您拥有所选**执行角色**的权限。否则，您可以创建新角色。

1. 在**其他配置**下，选择**计算类型**作为 **Lambda 托管实例**。

1. 应预先选择您在之前步骤中创建的容量提供程序的容量提供程序 ARN。

1. 选择**内存大小**和**每个 vCPU 的执行环境内存（GiB）比率**。

1. 选择**创建函数**。

您的 Lambda 托管实例函数已创建，并且将为您指定的容量提供程序预置容量。创建函数通常需要几分钟时间。完成后，您可以编辑函数代码并运行第一个测试。

## 创建 Lambda 托管实例函数（AWS CLI）
<a name="lambda-managed-instances-getting-started-cli"></a>

### 先决条件
<a name="lambda-managed-instances-prerequisites"></a>

在开始之前，请确保您具有以下各项：
+ **AWS CLI**：安装和配置 AWS CLI。有关更多信息，请参阅[安装或更新最新版本的 AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)。
+ **IAM 权限**：您的 IAM 用户或角色必须具有创建 Lambda 函数、容量提供程序和传递 IAM 角色的权限。请注意，如果这是首次在账户中创建容量提供程序，或者如果服务相关角色（SLR）已删除，您也将需要 `iam:CreateServiceLinkedRole`。

### 步骤 1：创建所需的 IAM 角色
<a name="lambda-managed-instances-step1-iam"></a>

Lambda 托管实例需要两个 IAM 角色：您的函数的执行角色和容量提供程序的操作员角色。操作员角色使 Lambda 能够代表您启动、终止和监控 Amazon EC2 实例。函数的执行角色授予函数访问其他 AWS 服务和资源的权限。

**创建 Lambda 执行角色**

1. 创建一个信任策略文档，该文档允许 Lambda 代入该角色：

   ```
   cat > lambda-trust-policy.json << 'EOF'
   {
     "Version": "2012-10-17",		 	 	 
     "Statement": [
       {
         "Effect": "Allow",
         "Principal": {
           "Service": "lambda.amazonaws.com"
         },
         "Action": "sts:AssumeRole"
       }
     ]
   }
   EOF
   ```

1. 创建执行角色：

   ```
   aws iam create-role \
     --role-name MyLambdaExecutionRole \
     --assume-role-policy-document file://lambda-trust-policy.json
   ```

1. 附上基本执行策略：

   ```
   aws iam attach-role-policy \
     --role-name MyLambdaExecutionRole \
     --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
   ```

**要创建容量提供程序操作员角色**

1. 创建一个信任策略文档，该文档允许 Lambda 代入操作员角色：

   ```
   cat > operator-trust-policy.json << 'EOF'
   {
     "Version": "2012-10-17",		 	 	 
     "Statement": [
       {
         "Effect": "Allow",
         "Principal": {
           "Service": "lambda.amazonaws.com"
         },
         "Action": "sts:AssumeRole"
       }
     ]
   }
   EOF
   ```

1. 创建操作员角色：

   ```
   aws iam create-role \
     --role-name MyCapacityProviderOperatorRole \
     --assume-role-policy-document file://operator-trust-policy.json
   ```

1. 附上所需的 EC2 权限策略：

   ```
   aws iam attach-role-policy \
     --role-name MyCapacityProviderOperatorRole \
     --policy-arn arn:aws:iam::aws:policy/AWSLambdaManagedEC2ResourceOperator
   ```

### 步骤 2：设置 VPC 资源
<a name="lambda-managed-instances-step2-vpc"></a>

Lambda 托管实例在您的 VPC 中运行，并且需要子网和安全组。

**要创建 VPC 资源**

1. 创建 VPC：

   ```
   VPC_ID=$(aws ec2 create-vpc \
     --cidr-block 10.0.0.0/16 \
     --query 'Vpc.VpcId' \
     --output text)
   ```

1. 创建子网：

   ```
   SUBNET_ID=$(aws ec2 create-subnet \
     --vpc-id $VPC_ID \
     --cidr-block 10.0.1.0/24 \
     --query 'Subnet.SubnetId' \
     --output text)
   ```

1. 创建安全组：

   ```
   SECURITY_GROUP_ID=$(aws ec2 create-security-group \
     --group-name my-capacity-provider-sg \
     --description "Security group for Lambda Managed Instances" \
     --vpc-id $VPC_ID \
     --query 'GroupId' \
     --output text)
   ```

**注意：**您的 Lambda 托管实例函数需要进行 VPC 配置，以便能够访问 VPC 之外的资源，并将遥测数据传输至 CloudWatch Logs 和 X-Ray。有关配置的详细信息，请参阅 [Lambda 托管实例的联网](lambda-managed-instances-networking.md)。

### 步骤 3：创建容量提供程序
<a name="lambda-managed-instances-step3-capacity-provider"></a>

容量提供程序管理运行您的 Lambda 函数的 EC2 实例。

**创建容量提供程序**

```
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)

aws lambda create-capacity-provider \
  --capacity-provider-name my-capacity-provider \
  --vpc-config SubnetIds=[$SUBNET_ID],SecurityGroupIds=[$SECURITY_GROUP_ID] \
  --permissions-config CapacityProviderOperatorRoleArn=arn:aws:iam::${ACCOUNT_ID}:role/MyCapacityProviderOperatorRole \
  --instance-requirements Architectures=[x86_64] \
  --capacity-provider-scaling-config MaxVCpuCount=30
```

此命令采用以下配置创建容量提供程序：
+ **VPC 配置**：指定 EC2 实例的子网和安全组
+ **权限**：定义 Lambda 用于管理 EC2 实例的 IAM 角色
+ **实例要求**：指定 x86\$164 架构
+ **扩展配置**：为容量提供程序设置最多 30 个 vCPU

### 步骤 4：创建包含内联代码的 Lambda 函数
<a name="lambda-managed-instances-step4-function"></a>

**要创建包含内联代码的函数**

1. 首先，创建一个简单的 Python 函数并将其内联打包：

   ```
   # Create a temporary directory for the function code
   mkdir -p /tmp/my-lambda-function
   cd /tmp/my-lambda-function
   
   # Create a simple Python handler
   cat > lambda_function.py << 'EOF'
   import json
   
   def lambda_handler(event, context):
       return {
           'statusCode': 200,
           'body': json.dumps({
               'message': 'Hello from Lambda Managed Instances!',
               'event': event
           })
       }
   EOF
   
   # Create a ZIP file
   zip function.zip lambda_function.py
   ```

1. 使用内联 ZIP 文件创建 Lambda 函数：

   ```
   ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
   REGION=$(aws configure get region)
   
   aws lambda create-function \
     --function-name my-managed-instance-function \
     --package-type Zip \
     --runtime python3.13 \
     --handler lambda_function.lambda_handler \
     --zip-file fileb:///tmp/my-lambda-function/function.zip \
     --role arn:aws:iam::${ACCOUNT_ID}:role/MyLambdaExecutionRole \
     --architectures x86_64 \
     --memory-size 2048 \
     --ephemeral-storage Size=512 \
     --capacity-provider-config LambdaManagedInstancesCapacityProviderConfig={CapacityProviderArn=arn:aws:lambda:${REGION}:${ACCOUNT_ID}:capacity-provider:my-capacity-provider}
   ```

   该函数通过以下方法创建：
   + **运行时**：Python 3.13
   + **处理程序**：`lambda_function.py` 中的 `lambda_handler` 函数
   + **内存**：2048MB
   + **临时存储**：512MB
   + **容量提供程序**：指向您创建的容量提供程序的链接

### 步骤 5：发布函数版本
<a name="lambda-managed-instances-step5-publish"></a>

要在 Lambda 托管实例上运行您的函数，您必须发布一个版本。

**要发布函数版本**

```
aws lambda publish-version \
  --function-name my-managed-instance-function
```

此命令会发布您的函数的第 1 版，并将其部署到容量提供程序。

### 第 6 步：调用函数
<a name="lambda-managed-instances-step6-invoke"></a>

发布之后，您可以调用函数。

**要调用函数**

```
aws lambda invoke \
  --function-name my-managed-instance-function:1 \
  --payload '{"name": "World"}' \
  response.json

# View the response
cat response.json
```

该函数在您的容量提供程序管理的 EC2 实例上运行并返回响应。

### 清理
<a name="lambda-managed-instances-cleanup"></a>

为避免产生费用，请删除您创建的资源：

1. 删除函数：

   ```
   aws lambda delete-function --function-name my-managed-instance-function
   ```

1. 删除容量提供程序：

   ```
   aws lambda delete-capacity-provider --capacity-provider-name my-capacity-provider
   ```

1. 删除 VPC 资源：

   ```
   aws ec2 delete-security-group --group-id $SECURITY_GROUP_ID
   aws ec2 delete-subnet --subnet-id $SUBNET_ID
   aws ec2 delete-vpc --vpc-id $VPC_ID
   ```

1. 删除 IAM 角色：

   ```
   aws iam detach-role-policy \
     --role-name MyLambdaExecutionRole \
     --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
   aws iam detach-role-policy \
     --role-name MyCapacityProviderOperatorRole \
     --policy-arn arn:aws:iam::aws:policy/AWSLambdaManagedEC2ResourceOperator
   
   aws iam delete-role --role-name MyLambdaExecutionRole
   aws iam delete-role --role-name MyCapacityProviderOperatorRole
   ```

# 核心概念
<a name="lambda-managed-instances-core-concepts"></a>

Lambda 托管实例引入了几个不同于传统 Lambda 函数的核心概念。理解这些概念对于在 EC2 基础设施上有效地部署和管理您的函数至关重要。

**容量提供程序**构成了 Lambda 托管实例的基础。容量提供程序会定义您的函数执行所依赖的计算基础设施，其中包括 VPC 配置、实例要求以及扩展策略。容量提供程序还充当您的函数的安全边界，这意味着分配给同一容量提供程序的所有函数必须相互信任。

**扩展行为**完全不同于传统 Lambda 函数。与在调用到达时按需扩展不同，托管实例是根据 CPU 资源利用率进行异步扩展的。这种方法消除了冷启动，但需要对流量增长进行规划。如果您的流量在 5 分钟内增长超过一倍，则您可能会遇到节流现象，因为 Lambda 会纵向扩展容量以满足需求。

需要仔细考虑**安全和权限**。您需要拥有操作员角色权限，以便让 Lambda 能够在您的容量提供程序中管理 EC2 资源。此外，用户还需要 `lambda:PassCapacityProvider` 权限来将函数分配给容量提供程序，这就像一道安全闸门，用于控制哪些函数能够在特定的基础设施上运行。

**多并发执行**是托管实例的一个关键特征。每个执行环境都能够同时处理多个调用，从而最大程度地提高 IO 密集型应用程序的资源利用率。这与传统的 Lambda 有所不同，在传统的 Lambda 中，每个环境一次处理一个请求。这种执行模型需要根据您的运行时来关注线程安全性、状态管理以及上下文隔离等。

以下部分提供有关每个核心概念的详细信息。

# 容量提供程序
<a name="lambda-managed-instances-capacity-providers"></a>

容量提供程序是运行 Lambda 托管实例的基础。它充当您的函数的安全边界，并定义 Lambda 将代表您预置和管理的计算资源。

在创建容量提供程序时，您将指定：
+ **VPC 配置**：实例将在其中运行的子网和安全组
+ **权限**：Lambda 用于管理 EC2 资源的 IAM 角色
+ **实例要求**（可选）：架构和[实例类型](https://aws.amazon.com/lambda/pricing/#:~:text=EPU%20pricing%20applies.-,Management%20Fees,-Pricing%20Example%3A%20High)首选项
+ **扩展配置**（可选）：Lambda 如何扩展您的实例

## 将容量提供程序理解为安全边界
<a name="lambda-managed-instances-capacity-provider-security-boundary"></a>

容量提供程序充当您的 VPC 中 Lambda 函数的安全边界，取代了基于 FireCracker 的隔离。函数在实例内的容器中执行，但与 Firecracker microVM 不同的是，这些容器并不能为函数之间提供强大的安全隔离。

**关键安全概念：**
+ **容量提供程序：**定义 Lambda 函数信任级别的安全边界
+ **容器隔离：**容器本身并非安全提供者——切勿将它们用于不受信任的工作负载之间的安全防护。
+ **信任分离：**通过使用不同的容量提供程序来分离那些彼此不互信的工作负载

## 创建容量提供程序
<a name="lambda-managed-instances-creating-capacity-provider"></a>

您可以使用 AWS CLI、AWS 管理控制台或 AWS SDK 创建容量提供程序。

**使用 AWS CLI：**

```
aws lambda create-capacity-provider \
  --capacity-provider-name my-capacity-provider \
  --vpc-config SubnetIds=subnet-12345,subnet-67890,subnet-11111,SecurityGroupIds=sg-12345 \
  --permissions-config CapacityProviderOperatorRoleArn=arn:aws:iam::123456789012:role/MyOperatorRole \
  --instance-requirements Architectures=x86_64 \
  --capacity-provider-scaling-config ScalingMode=Auto
```

### 必需参数
<a name="lambda-managed-instances-capacity-provider-required-params"></a>

**CapacityProviderName**
+ 您的容量提供程序的唯一名称
+ 在您的 AWS 账户中必须是唯一的

**VpcConfig**
+ **SubnetIds**（必填）：至少一个子网，最多 16 个。在多个可用区之间使用子网以增强韧性
+ **SecurityGroupIds**（可选）：您的实例的安全组。如果未指定，则默认为 VPC 的默认安全组

**PermissionsConfig**
+ **CapacityProviderOperatorRoleArn**（必填）：允许 Lambda 在容量提供程序中管理 EC2 资源的 IAM 角色

### 可选参数
<a name="lambda-managed-instances-capacity-provider-optional-params"></a>

**InstanceRequirements**

为您的容量提供程序指定架构和[实例类型](https://aws.amazon.com/lambda/pricing/#:~:text=EPU%20pricing%20applies.-,Management%20Fees,-Pricing%20Example%3A%20High)：
+ **架构**：选择 `x86_64` 或 `arm64`。默认为 `x86_64`
+ **AllowedInstanceTypes**：指定允许的实例类型。示例：`m5.8xlarge`
+ **ExcludedInstanceTypes**：使用通配符指定排除的实例类型。您只能指定 AllowedInstanceTypes 或 ExcludedInstanceTypes 中的一种

默认情况下，Lambda 会为工作负载选择最佳实例类型。我们建议让 Lambda 托管实例为您选择实例类型，因为限制可能的实例类型数量可能会导致可用性降低。

**CapacityProviderScalingConfig**

配置 Lambda 扩展您的实例的方式：
+ **ScalingMode**：对于自动扩缩，设置为 `Auto`，或者对于手动控制，设置为 `Manual`。默认为 `Auto`
+ **MaxVCpuCount**：容量提供程序的最大 vCPU 数量。默认值为 400。
+ **ScalingPolicies**：为 CPU 和内存利用率定义目标跟踪扩展策略

**KmsKeyArn**

指定一个 AWS KMS 密钥进行 EBS 加密。如果未指定，则默认为 AWS 托管密钥。

**标签**

添加标签以组织和管理您的容量提供程序。

## 管理容量提供程序
<a name="lambda-managed-instances-managing-capacity-providers"></a>

### 更新容量提供程序
<a name="lambda-managed-instances-updating-capacity-provider"></a>

您可以使用 `UpdateCapacityProvider` API 更新容量提供程序的某些属性。

```
aws lambda update-capacity-provider \
  --capacity-provider-name my-capacity-provider \
  --capacity-provider-scaling-config ScalingMode=Auto
```

### 删除容量提供程序
<a name="lambda-managed-instances-deleting-capacity-provider"></a>

当您不再需要某个容量提供程序时，您可以使用 `DeleteCapacityProvider` API 将其删除。

```
aws lambda delete-capacity-provider \
  --capacity-provider-name my-capacity-provider
```

**注意：**您无法删除已附加了函数版本的容量提供程序。

### 查看容量提供程序详细信息
<a name="lambda-managed-instances-viewing-capacity-provider"></a>

使用 `GetCapacityProvider` API 检索有关容量提供程序的信息。

```
aws lambda get-capacity-provider \
  --capacity-provider-name my-capacity-provider
```

## 容量提供程序状态
<a name="lambda-managed-instances-capacity-provider-states"></a>

容量提供程序可以处于以下状态之一：
+ **待处理**：正在创建容量提供程序
+ **活动**：容量提供程序已准备好投入使用
+ **失败**：创建容量提供程序失败
+ **正在删除**：正在删除容量提供程序

## 配额
<a name="lambda-managed-instances-capacity-provider-quotas"></a>
+ **每个账户的最大容量提供程序数**：1000
+ **每个容量提供程序的最大函数版本数**：100（无法增加）

## 最佳实践
<a name="lambda-managed-instances-capacity-provider-best-practices"></a>

1. **按信任级别分离**：为具有不同安全要求的工作负载创建不同的容量提供程序

1. **使用描述性名称**：对容量提供程序进行命名，以清楚地表明其预期用途和信任级别（例如 `production-trusted`、`dev-sandbox`）。

1. **使用多个可用区**：在多个可用区中指定子网以提供高可用性。

1. **让 Lambda 选择实例类型**：除非有特定硬件要求，否则请允许 Lambda 选择最佳实例类型以确保可用性

1. **监控使用情况**：使用 AWS CloudTrail 监控容量提供程序的分配和访问模式

## 后续步骤
<a name="lambda-managed-instances-capacity-provider-next-steps"></a>
+ 了解有关[扩展 Lambda 托管实例](lambda-managed-instances-scaling.md)的信息
+ 了解 [Lambda 托管实例的安全和权限](lambda-managed-instances-security.md)
+ [为您的容量提供程序配置 VPC 连接](lambda-managed-instances-networking.md)
+ 查看 [Java](lambda-managed-instances-java-runtime.md)、[Node.js](lambda-managed-instances-nodejs-runtime.md) 和 [Python](lambda-managed-instances-python-runtime.md) 的运行时特定指南

# 扩展 Lambda 托管实例
<a name="lambda-managed-instances-scaling"></a>

Lambda 托管实例不会在调用到达时进行扩展，并且不支持冷启动。相反，它通过资源消耗信号进行异步扩展。托管实例目前根据 CPU 资源利用率和多并发饱和状态进行扩展。

**主要区别：**
+ **Lambda（默认）：**当没有可用的执行环境来处理传入的调用时（冷启动）进行扩展
+ **Lambda 托管实例：**根据 CPU 资源利用率和执行环境的多并发饱和状态进行异步扩展

如果您的流量在 5 分钟内增长超过一倍，您可能会在 Lambda 纵向扩展实例和执行环境以满足需求时看到节流出现。

## 扩缩生命周期
<a name="lambda-managed-instances-scaling-lifecycle"></a>

Lambda 托管实例使用分布式架构来管理扩缩：

**组件：**
+ **托管实例**：在您的账户中，于您提供的子网内运行
+ **路由器和扩缩器**：用于路由调用和管理扩缩的共享 Lambda 组件
+ **Lambda 代理**：在每个托管实例上运行，以管理执行环境生命周期并监控资源消耗情况

**工作原理：**

1. 当您使用容量提供程序发布函数版本时，Lambda 会在您的账户中启动托管实例。默认情况下，它会启动三个实例以实现可用区的容错功能，并在将您的函数版本标记为 ACTIVE 之前启动三个执行环境。

1. 每个托管实例都可以为映射到同一个容量提供程序的多个函数运行执行环境。

1. 随着流量进入您的应用程序，执行环境会消耗资源。Lambda 代理会向扩缩器发送通知，后者则会决定是否要扩展新的执行环境或托管实例。

1. 如果路由器尝试向资源消耗较高的执行环境发送调用，则该实例上的 Lambda 代理会通知它在另一个执行环境上重试。

1. 随着流量的减少，Lambda 代理会通知扩缩器，后者会做出决定，即纵向缩减执行环境并横向缩减托管实例。

## 调整扩缩行为
<a name="lambda-managed-instances-adjusting-scaling"></a>

您可以通过四个控件自定义托管实例的扩缩行为：

### 函数级别控件
<a name="lambda-managed-instances-function-level-controls"></a>

#### 1. 函数内存和 vCPU
<a name="lambda-managed-instances-function-memory-vcpus"></a>

为您的函数选择内存大小和 vCPU 分配量。支持的最小函数大小为 2GB 和 1 个 vCPU。

**注意事项：**
+ 选择能够支持您的函数的多并发执行的内存和 vCPU 设置。
+ 您不能为函数配置少于 1 个 vCPU，因为托管实例上运行的函数应能够支持多并发工作负载。
+ 您不能选择低于 2GB，因为这符合 c 实例 2:1 的内存与 vCPU 比（这种比例是所有比例中最低的）
+ 对于 Python 应用程序，由于 Python 处理多并发的方式，您可能需要选择较高的内存与 vCPU 比（例如 4:1 或 8:1）
+ 如果您正在运行 CPU 密集型操作或执行的 IO 很少，则应选择多个 vCPU

#### 2. 最大并发数
<a name="lambda-managed-instances-maximum-concurrency"></a>

为每个执行环境设置最大并发数

**默认行为：**Lambda 选择合理的默认设置，这些设置能平衡资源消耗与吞吐量，同时适用于各种各样的应用程序。

**调整指南：**
+ **提高并发数：**如果您的函数调用所占用的 CPU 极少，可提高最大并发数（最高至每个 vCPU 64 个）
+ **降低并发数：**如果您的应用程序占用大量内存但 CPU 使用率很低，您可以降低最大并发数

**重要提示：**由于 Lambda 托管实例适用于多并发应用程序，因此并发度极低的执行环境在进行扩缩时可能会遇到节流的情况。

### 容量提供程序级别控件
<a name="lambda-managed-instances-capacity-provider-level-controls"></a>

#### 3. 目标资源利用率
<a name="lambda-managed-instances-target-resource-utilization"></a>

选择您自己的 CPU 利用率消耗目标。

**默认行为：**Lambda 会保留足够的余量，让您的流量在 5 分钟翻倍也不会受到节流。

**优化选项：**
+ 如果您的工作负载非常稳定或者您的应用程序对节流不敏感，您可以将目标设定得较高，以实现更高的利用率和更低的成本。
+ 如果您希望为突发流量留出足够的空间，可以将资源目标设定为较低水平，这样就需要更大的容量

#### 4. 实例类型选择
<a name="lambda-managed-instances-instance-type-selection"></a>

设置允许或排除的实例类型。

**默认行为：**Lambda 会为您的工作负载选择最佳实例类型。我们建议让 Lambda 托管实例为您选择实例类型，因为限制可能的实例类型数量可能会导致可用性降低。

**自定义配置：**
+ **特定的硬件要求：**将允许的实例类型设置为兼容的实例列表。例如，如果您的应用程序需要较高的网络带宽，您可以选择多种 n 系列实例类型。
+ **成本优化：**对于测试或开发环境，您可以选择较小的实例类型，例如 m7a.large 实例类型

## 后续步骤
<a name="lambda-managed-instances-scaling-next-steps"></a>
+ 了解 [Lambda 托管实例的容量提供程序](lambda-managed-instances-capacity-providers.md)
+ 查看特定于运行时的指南，了解如何处理多并发
+ [为您的容量提供程序配置 VPC 连接](lambda-managed-instances-networking.md)
+ 监控扩缩指标以优化扩缩行为

# 安全性和权限
<a name="lambda-managed-instances-security"></a>

Lambda 托管实例使用**容量提供程序作为信任边界**。函数在这些实例内的容器中执行，但容器并不能为工作负载之间提供安全隔离。分配给同一容量提供程序的所有函数必须相互信任。

## 关键安全概念
<a name="lambda-managed-instances-key-security-concepts"></a>
+ **容量提供程序**：定义 Lambda 函数信任级别的安全边界
+ **容器隔离**：容器本身并非安全边界——切勿将它们用于不受信任的工作负载之间的安全防护。
+ **信任分离**：通过使用不同的容量提供程序来分离那些彼此不互信的工作负载

## 所需权限
<a name="lambda-managed-instances-required-permissions"></a>

### PassCapacityProvider 操作
<a name="lambda-managed-instances-pass-capacity-provider"></a>

用户需要 `lambda:PassCapacityProvider` 权限才能将函数分配给容量提供程序。此权限充当安全门，确保只有经过授权的用户才能将函数放置到特定的容量提供程序中。

账户管理员通过 `lambda:PassCapacityProvider` IAM 操作控制哪些函数可以使用特定的容量提供程序。在以下情况下需要执行此操作：
+ 创建使用 Lambda 托管实例的函数
+ 更新函数配置以使用容量提供程序
+ 通过基础设施即代码部署函数

**示例 IAM 策略**

```
{
  "Version": "2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "lambda:PassCapacityProvider",
      "Resource": "arn:aws:lambda:*:*:capacity-provider:trusted-workloads-*"
    }
  ]
}
```

### 服务相关角色
<a name="lambda-managed-instances-service-linked-role"></a>

AWS Lambda 使用 `AWSServiceRoleForLambda` 服务相关角色来管理您的容量提供程序中的 Lambda 托管实例 ec2 资源。

## 最佳实践
<a name="lambda-managed-instances-security-best-practices"></a>

1. **按信任级别分离**：为具有不同安全要求的工作负载创建不同的容量提供程序

1. **使用描述性名称**：对容量提供程序进行命名，以清楚地表明其预期用途和信任级别（例如 `production-trusted`、`dev-sandbox`）。

1. **应用最低权限**：仅向必要的容量提供程序授予 `PassCapacityProvider` 权限

1. **监控使用情况**：使用 AWS CloudTrail 监控容量提供程序的分配和访问模式

## 后续步骤
<a name="lambda-managed-instances-security-next-steps"></a>
+ 了解 [Lambda 托管实例的容量提供程序](lambda-managed-instances-capacity-providers.md)
+ 了解 [Lambda 托管实例的扩展](lambda-managed-instances-scaling.md)
+ [为您的容量提供程序配置 VPC 连接](lambda-managed-instances-networking.md)
+ 查看 [Java](lambda-managed-instances-java-runtime.md)、[Node.js](lambda-managed-instances-nodejs-runtime.md) 和 [Python](lambda-managed-instances-python-runtime.md) 的运行时特定指南

# Lambda 托管实例的 Lambda 操作员角色
<a name="lambda-managed-instances-operator-role"></a>

当您使用 Lambda 托管实例时，Lambda 需要获得管理您账户内的计算容量的权限。操作员角色通过 IAM 策略提供这些权限，使得 Lambda 能够在容量提供程序中管理 EC2 实例。

Lambda 在执行这些管理操作时代入操作员角色，这与您的函数运行时 Lambda 代入执行角色的方式类似。

## 创建操作员角色
<a name="lambda-managed-instances-creating-operator-role"></a>

您可以在 IAM 控制台中或使用 AWS CLI 创建操作员角色。该角色必须包括：
+ **权限策略**：授予管理容量提供程序和相关资源的权限
+ **信任策略**：允许 Lambda 服务（`lambda.amazonaws.com`）代入角色

### 权限策略
<a name="lambda-managed-instances-operator-role-permissions-policy"></a>

操作员角色需要管理容量提供程序和底层计算资源的权限。该角色至少需要 [AWSLambdaManagedEC2ResourceOperator](https://us-east-1.console.aws.amazon.com/iam/home?region=us-east-1#/policies/details/arn%3Aaws%3Aiam%3A%3Aaws%3Apolicy%2FAWSLambdaManagedEC2ResourceOperator) 托管策略中的权限，目前为：

```
{
  "Version": "2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ec2:RunInstances",
        "ec2:CreateTags",
        "ec2:AttachNetworkInterface"
      ],
      "Resource": [
        "arn:aws:ec2:*:*:instance/*",
        "arn:aws:ec2:*:*:network-interface/*",
        "arn:aws:ec2:*:*:volume/*"
      ],
      "Condition": {
        "StringEquals": {
          "ec2:ManagedResourceOperator": "scaler.lambda.amazonaws.com"
        }
      }
    },
    {
      "Effect": "Allow",
      "Action": [
        "ec2:DescribeAvailabilityZones",
        "ec2:DescribeCapacityReservations",
        "ec2:DescribeInstances",
        "ec2:DescribeInstanceStatus",
        "ec2:DescribeInstanceTypeOfferings",
        "ec2:DescribeInstanceTypes",
        "ec2:DescribeSecurityGroups",
        "ec2:DescribeSubnets"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "ec2:RunInstances",
        "ec2:CreateNetworkInterface"
      ],
      "Resource": [
        "arn:aws:ec2:*:*:subnet/*",
        "arn:aws:ec2:*:*:security-group/*"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "ec2:RunInstances"
      ],
      "Resource": [
        "arn:aws:ec2:*:*:image/*"
      ],
      "Condition": {
        "StringEquals": {
          "ec2:Owner": "amazon"
        }
      }
    }
  ]
}
```

### 信任策略
<a name="lambda-managed-instances-operator-role-trust-policy"></a>

信任策略允许 Lambda 代入操作员角色：

```
{
  "Version": "2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

## Lambda 托管实例的服务相关角色
<a name="lambda-managed-instances-service-linked-role-for-lmi"></a>

为了负责任地管理 Lambda 托管实例的生命周期，Lambda 需要持续拥有访问权限，以便在您的账户中终止托管实例。Lambda 使用 AWS Identity and Access Management（IAM）服务相关角色（SLR）来执行这些操作。

**自动创建**：服务相关角色在您首次创建容量提供程序时将自动创建。创建第一个容量提供程序的用户必须拥有 `lambda.amazonaws.com` 主体的 `iam:CreateServiceLinkedRole` 权限。

**权限**：服务相关角色授予 Lambda 对托管实例的以下权限：
+ `ec2:TerminateInstances`：在实例生命周期结束时将其终止
+ `ec2:DescribeInstances`：枚举托管实例

**删除**：只有在您删除了账户中的所有 Lambda 托管实例容量提供程序之后，才能删除此服务相关角色。

有关服务关联角色的更多信息，请参阅[使用 Lambda 的服务相关角色](using-service-linked-roles.md)。

# 了解 Lambda 托管实例执行环境
<a name="lambda-managed-instances-execution-environment"></a>

Lambda 托管实例提供了一种备选部署模式，即在客户自有的 Amazon EC2 实例上运行您的函数代码，而 Lambda 则负责管理相关运营事务。托管实例的执行环境与 Lambda（默认）函数存在多个重要差异，尤其是在处理并发调用和管理容器生命周期方面。

**注意：**有关 Lambda（默认）执行环境的信息，请参阅了解 Lambda 执行环境生命周期。

## 执行环境生命周期
<a name="lambda-managed-instances-execution-lifecycle"></a>

Lambda 托管实例函数执行环境的生命周期与 Lambda（默认）在几个关键方面有所不同：

### Init 阶段
<a name="lambda-managed-instances-init-phase"></a>

在初始化阶段，Lambda 会执行以下步骤：
+ 初始化并注册所有扩展程序
+ 引导运行时入口点。运行时会启动所配置数量的运行时工作进程（实施取决于运行时）
+ 运行函数初始化代码（处理程序之外的代码）
+ 等待至少一个运行时工作进程通过调用 `/runtime/invocation/next` 发出准备就绪信号

当扩展程序已初始化并且至少有一个运行时工作进程已调用 `/runtime/invocation/next` 时，初始化阶段即被视为已完成。然后，该函数即准备好处理调用。

**注意**  
对于 Lambda 托管实例函数，初始化最长需要 15 分钟。超时时间为最大值 130 秒，或者为配置的函数超时时间（最长可达 900 秒）。

### 调用阶段
<a name="lambda-managed-instances-invoke-phase"></a>

Lambda 托管实例函数的调用阶段具有几个独特的特征：

**持续运行。**与 Lambda（默认）不同的是，其执行环境始终处于持续运行状态，能够实时处理接收到的调用，而不会在每次调用之间出现停滞。

**并行处理。**在同一个执行环境中，可以同时进行多次调用，每项调用都会由不同的运行时工作进程来处理。

**独立超时。**该函数的配置超时适用于每次单独的调用。当一次调用超时后，Lambda 会将该特定调用标记为失败，但不会中断其他正在运行的调用或终止执行环境。

**背压处理。**如果所有运行时工作进程都在忙于处理调用，那么新的调用请求将会被拒绝，直到有工作进程可用为止。

## 错误处理和恢复
<a name="lambda-managed-instances-error-handling"></a>

Lambda 托管实例函数执行环境中的错误处理与 Lambda（默认）不同：

**调用超时。**当单个调用超时后，Lambda 会为该调用返回超时错误。然而，Lambda 托管实例不会强制超时，您的代码将继续运行。作为函数开发人员，您负责检测和处理超时。上下文对象会显示调用的剩余时间，零或负值表示超时。执行环境中的其他并发调用继续正常处理。

**运行时工作进程故障。**如果某个运行时工作进程崩溃，执行环境会继续依靠其余正常运行的工作进程来维持运行。

**扩展程序崩溃。**如果扩展进程在初始化或操作期间崩溃，则整个执行环境将被标记为不正常并被终止。Lambda 会创建一个新的执行环境来替换它。

**无法重置/修复。**与 Lambda（默认）不同的是，托管实例不会在出错后尝试重置和重新初始化执行环境。相反，运行状况不佳的容器会被终止并由新的容器替代。

# Lambda 托管实例中的 \$1LATEST.PUBLISHED 版本
<a name="lambda-managed-instances-version-publishing"></a>

Lambda 托管实例函数支持与 Lambda（默认）相同的编号版本控制工作流程。如果您不想维护编号版本，Lambda 托管实例会引入一种新的版本类型：`$LATEST.PUBLISHED`。此版本允许您根据需要创建或重新发布最新发布的版本（可包含更新后的代码或配置），而无需管理编号版本。

**与 \$1LATEST 的主要区别**：当您使用非限定性 ARN 调用 Lambda 托管实例函数时，Lambda 会隐式调用 `$LATEST.PUBLISHED` 版本而不是未发布的 \$1LATEST 版本。

以下 AWS CLI 命令会创建或重新发布 `$LATEST.PUBLISHED` 版本。

```
aws lambda publish-version --function-name my-function --publish-to LATEST_PUBLISHED
```

您应看到以下输出：

```
{
  "FunctionName": "my-function",
  "FunctionArn": "arn:aws:lambda:us-east-2:123456789012:function:my-function:$LATEST.PUBLISHED",
  "Version": "$LATEST.PUBLISHED",
  "Role": "arn:aws:iam::123456789012:role/lambda-role",
  "Handler": "function.handler",
  "Runtime": "nodejs24.x",
  ...
}
```

**注意**  
如果您使用 AWS CloudFormation 或 Lambda 控制台创建 Lambda 托管实例函数，则 Lambda 会自动创建 `$LATEST.PUBLISHED` 版本。

# 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 不支持将 `_X_AMZN_TRACE_ID` 环境变量用于 Lambda 托管实例。使用 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 SDK for Java 2.0：版本 2.34.0 或更高版本
+ AWS X-Ray SDK for Java：版本 2.20.0 或更高版本
+ 适用于 OpenTelemetry 的 AWS Distro - 适用于 Java 的检测工具：版本 2.20.0 或更高版本
+ 适用于 AWS Lambda 的 Powertools（Java）：版本 2.8.0 或更高版本

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

适用于 AWS Lambda 的 Powertools（Java）与 Lambda 托管实例兼容，并提供用于日志记录、跟踪、指标等的实用工具。有关更多信息，请参阅[适用于 AWS Lambda 的 Powertools（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` 的执行的工作线程来处理并发请求。函数初始化会在每个工作线程中发生一次。并发调用在两个维度上得到处理：工作线程在各个 vCPU 上实现并行处理，而异步执行则在每个线程内部实现并发。由同一个工作线程处理的每个并发请求都共享同一个处理程序对象和全局状态，因此需要在多个并发请求下进行安全处理。

## 最大并发数
<a name="lambda-managed-instances-nodejs-max-concurrency"></a>

Lambda 向每个执行环境发送的最大并发请求数由函数配置中的 `PerExecutionEnvironmentMaxConcurrency` 设置控制。这是一项可选设置，其默认值因运行时而异。对于 Node.js 运行时而言，其默认设置为每个 vCPU 64 个并发请求，或者您也可以自行配置其他数值。Lambda 会根据每个执行环境吸收这些请求的容量，自动调整并发请求的数量，最高到配置的最大值。

对于 Node.js，每个执行环境能够处理的并发请求数量取决于工作线程的数量以及每个工作线程异步处理并发请求的能力。工作线程的默认数量由可用的 vCPU 数量决定，或者您可以通过设置 `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 不支持将 `_X_AMZN_TRACE_ID` 环境变量用于 Lambda 托管实例。使用 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（默认）函数也可以使用 `process.on()` 订阅 SIGTERM 信号。使用 Lambda 托管实例的函数不支持此功能，因为 `process.on()` 不能与工作线程一起使用。要了解有关执行环境生命周期的更多信息，请参阅 [了解 Lambda 执行环境生命周期](lambda-runtime-environment.md)。

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

Lambda 托管实例需要以下最低程序包版本：
+ AWS SDK for JavaScript v3：版本 3.933.0 或更高版本
+ AWS X-Ray SDK for Node.js：版本 3.12.0 或更高版本
+ 适用于 OpenTelemetry 的 AWS Distro - 适用于 JavaScript 的检测工具：版本 0.8.0 或更高版本
+ 适用于 AWS Lambda 的 Powertools（TypeScript）：版本 2.29.0 或更高版本

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

适用于 AWS Lambda 的 Powertools（TypeScript）与 Lambda 托管实例兼容，并提供用于日志记录、跟踪、指标等的实用工具。有关更多信息，请参阅[适用于 AWS Lambda 的 Powertools（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 与内存的比例，或者降低并发设置，以避免超出可用内存的容量。您可以在 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` 会自动包含在每个日志条目中。有关更多信息，请参阅[将 Lambda 高级日志记录控制与 Python 结合使用](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 的 Powertools（Python）：版本 3.23.0 或更高版本

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

适用于 AWS Lambda 的 Powertools（Python）与 Lambda 托管实例兼容，并提供用于日志记录、跟踪、指标等的实用工具。有关更多信息，请参阅[适用于 AWS Lambda 的 Powertools（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();

        ...
    }
}
```

要解决这个问题，请为每个请求使用从连接池中获取的单独连接。打开连接对象时，`Microsoft.Data.SqlClient` 之类的 ADO.NET 提供程序会自动支持连接池。

```
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` 会自动包含在每个日志条目中。有关更多信息，请参阅 [将 Lambda 高级日志记录控件与 .NET 结合使用](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 不支持将 `_X_AMZN_TRACE_ID` 环境变量用于 Lambda 托管实例。使用 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 或更高版本

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

[适用于 AWS Lambda (.NET) 的 Powertools](https://docs.aws.amazon.com/powertools/dotnet/)和 [适用于 OpenTelemetry 的 AWS Distro - 适用于 .Net 的检测工具](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 托管实例时，您应像在任何其他多线程环境中一样，采用相同的线程安全措施。由于处理程序对象在所有工作线程中是共享的，因此任何可变状态都必须是线程安全的。这包括集合、数据库连接以及在请求处理过程中被修改的任何静态对象。

要启用并发请求处理，请在 `Cargo.toml` 文件中添加 `concurrency-tokio` 功能标志。

```
[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 的[高级日志控制](monitoring-logs.md#monitoring-cloudwatchlogs-advanced)，使用 Lambda 托管实例的函数支持结构化 JSON 日志格式。此格式包括 `requestId`，使得日志条目能够与单个请求相关联。有关更多信息，请参阅 [使用 Tracing crate 实现高级日志记录](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 不支持将 `_X_AMZN_TRACE_ID` 环境变量用于 Lambda 托管实例。使用 AWS SDK for Rust 时，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。

# Lambda 托管实例的联网
<a name="lambda-managed-instances-networking"></a>

运行 Lambda 托管实例函数时，您需要配置网络连接，以使您的函数能够访问 VPC 外部的资源。这包括 Amazon S3 和 DynamoDB 等 AWS 服务。将遥测数据传输到 CloudWatch Logs 和 X-Ray 也需要此连接。

## 连接选项
<a name="lambda-managed-instances-connectivity-options"></a>

配置 VPC 连接有三种主要方法，每种方法在成本、安全性和复杂性方面都有不同的优缺点。

## 具有互联网网关的公有子网
<a name="lambda-managed-instances-public-subnet-igw"></a>

此选项采用公有子网，并通过互联网网关实现与互联网的直接连接。您可以在 IPv4 和 IPv6 配置之间进行选择。

### 具有互联网网关的 IPv4
<a name="lambda-managed-instances-ipv4-igw"></a>

**要使用互联网网关配置 IPv4 连接**

1. 创建或使用具有 IPv4 CIDR 数据块的现有公有子网。

1. 将 Internet 网关附加到 VPC。

1. 更新路由表以将 `0.0.0.0/0` 流量路由到互联网网关。

1. 确保已为资源分配公有 IPv4 地址或弹性 IP 地址。

1. 配置安全组，以允许在所需端口上进行出站流量传输。

此配置提供双向连接，既支持您的函数的出站连接，也支持来自互联网的入站连接。

### 具有互联网网关的 IPv6
<a name="lambda-managed-instances-ipv6-igw"></a>

**要使用互联网网关配置 IPv6 连接**

1. 在您的 VPC 上启用 IPv6。

1. 创建或使用分配了 IPv6 CIDR 数据块的现有公有子网。

1. 将互联网网关连接到您的 VPC（同一个互联网网关可以同时处理 IPv4 和 IPv6）。

1. 更新路由表以将 `::/0` 流量路由到互联网网关。

1. 确认您需要访问的 AWS 服务在您所在区域支持 IPv6。

1. 配置安全组，以允许在所需端口上进行出站流量传输。

此配置使用 IPv6 寻址提供双向连接。

### 带仅传出互联网网关的 IPv6
<a name="lambda-managed-instances-ipv6-egress-only"></a>

**要使用仅传出互联网网关配置 IPv6 连接**

1. 在您的 VPC 上启用 IPv6。

1. 创建或使用分配了 IPv6 CIDR 数据块的现有公有子网。

1. 将仅传出互联网网关连接到您的 VPC。

1. 更新路由表以将 `::/0` 流量路由到仅传出互联网网关。

1. 确认您需要访问的 AWS 服务在您所在区域支持 IPv6。

1. 配置安全组，以允许在所需端口上进行出站流量传输。

此配置提供仅限出站的连接，防止来自互联网的入站连接，同时允许您的函数启动出站连接。

## VPC 端点
<a name="lambda-managed-instances-vpc-endpoints"></a>

VPC 端点使您无需互联网网关、NAT 设备、VPN 连接或 AWS Direct Connect 连接即可将 VPC 私密地连接到支持的 AWS 服务。您的 VPC 和AWS服务之间的流量不会脱离 Amazon 网络。

**要配置 VPC 端点**

1. 通过 [console.aws.amazon.com/vpc/](https://console.aws.amazon.com/vpc/) 打开 Amazon VPC 控制台。

1. 在导航窗格中，选择**端点**。

1. 选择 **创建端点**。

1. 对于**服务类别**，选择 **AWS 服务**。

1. 对于**服务名称**，选择您需要的服务端点（例如，为 Amazon S3 选择 `com.amazonaws.region.s3`）。

1. 对于 **VPC**，选择您的 VPC。

1. 对于**子网**，选择要在其中创建端点网络接口的子网。要获得高可用性，在多个可用区中选择子网。

1. 对于**安全组**，选择要与端点网络接口关联的安全组。安全组必须在所需端口上允许来自您的函数安全组的入站流量。

1. 选择**创建端点**。

针对您的函数需要访问的每个 AWS 服务重复这些步骤。

## 具有 NAT 网关的私有子网
<a name="lambda-managed-instances-private-subnet-nat"></a>

该选项使用 NAT 网关为私有子网中的资源提供互联网访问，同时确保这些资源保持私有状态。

**要配置具有 NAT 网关的私有子网**

1. 使用 CIDR 数据块创建公有子网（如果尚不存在）。

1. 将 Internet 网关附加到 VPC。

1. 在公有子网中创建一个 NAT 网关，并分配弹性 IP 地址。

1. 更新公有子网路由表以添加路由：`0.0.0.0/0` → 互联网网关。

1. 创建或使用具有 CIDR 数据块的现有私有子网。

1. 更新私有子网路由表以添加路由：`0.0.0.0/0` → NAT 网关。

1. 配置安全组，以允许在所需端口上进行出站流量传输。

为了实现高可用性，请在每个可用区部署一个 NAT 网关，并对每个可用区的路由表进行配置，以使用本地 NAT 网关。这样可以防止跨可用区的数据传输费用并提高弹性。

## 选择连接选项
<a name="lambda-managed-instances-choosing-connectivity"></a>

在选择连接选项时，请考虑以下因素：

**带有互联网网关的公有子网**
+ 配置最简单，成本最低
+ 适用于开发和测试环境
+ 资源可以接收来自互联网的入站连接（安全考虑因素）
+ 同时支持 IPv4 和 IPv6

** VPC 端点**
+ 最高安全性，流量留存在 AWS 网络内
+ 与互联网路由相比，延迟更低
+ 推荐用于具有严格安全要求的生产环境
+ 每个端点、每个可用区以及处理的每 GB 数据的成本更高
+ 每个可用区都需要一个端点才能实现高可用性

**具有 NAT 网关的私有子网**
+ 资源保持私有性，没有入站互联网访问权限
+ 标准的企业架构模式
+ 支持所有的 IPv4 互联网流量
+ 成本适中，包括按小时收取 NAT 的网关费用和数据处理费
+ 仅支持 IPv4

## 后续步骤
<a name="lambda-managed-instances-networking-next-steps"></a>
+ 了解 [Lambda 托管实例的容量提供程序](lambda-managed-instances-capacity-providers.md)
+ 了解 [Lambda 托管实例的扩展](lambda-managed-instances-scaling.md)
+ 查看 [Java](lambda-managed-instances-java-runtime.md)、[Node.js](lambda-managed-instances-nodejs-runtime.md) 和 [Python](lambda-managed-instances-python-runtime.md) 的运行时特定指南
+ 了解 [Lambda 托管实例的安全和权限](lambda-managed-instances-security.md)

# 监控 Lambda 托管实例
<a name="lambda-managed-instances-monitoring"></a>

您可以通过 CloudWatch 指标来监控 Lambda 托管实例。Lambda 自动将指标发布至 CloudWatch，以帮助您监控资源使用情况、跟踪成本并优化性能。

## 可用指标
<a name="lambda-managed-instances-available-metrics"></a>

Lambda 托管实例提供两个级别的指标：容量提供程序级别和执行环境级别。

### 容量提供程序级别指标
<a name="lambda-managed-instances-capacity-provider-metrics"></a>

容量提供程序级别指标能够让您了解您的各个实例的整体资源使用情况。这些指标使用以下维度：
+ **CapacityProviderName**：您的容量提供程序的名称
+ **InstanceType**：EC2 实例类型

**资源利用率指标：**
+ **CPUUtilization**：容量提供程序中各实例的 CPU 利用率百分比
+ **MemoryUtilization**：容量提供程序中各实例的内存利用率百分比

**容量指标：**
+ **vCPUAvailable**：实例上可供分配的 vCPU 数量（计数）
+ **MemoryAvailable**：实例上可供分配的内存量（以字节为单位）
+ **vCPUAllocated**：实例上为执行环境分配的 vCPU 数量（计数）
+ **MemoryAllocated**：实例上为执行环境分配的内存量（以字节为单位）

### 执行环境级别指标
<a name="lambda-managed-instances-execution-environment-metrics"></a>

执行环境级别指标能够让我们了解各个函数的资源使用情况和并发情况。这些指标使用以下维度：
+ **CapacityProviderName**：您的容量提供程序的名称
+ **FunctionName**：您的 Lambda 函数的名称
+ **资源** - 按资源查看函数特定版本的指标。

**注意**  
对于 Lambda 托管实例 (LMI)，`Resource` 维度仅支持函数版本。格式为 `<FunctionName>:<FunctionVersion>`。

**可用的执行环境指标：**
+ **ExecutionEnvironmentConcurrency**：5 分钟采样期间的最大并发数
+ **ExecutionEnvironmentConcurrencyLimit**：每个执行环境的最大并发限制
+ **ExecutionEnvironmentCPUUtilization**：函数执行环境中 CPU 利用率的百分比
+ **ExecutionEnvironmentMemoryUtilization**：函数执行环境中内存利用率的百分比

## 指标频率和保留率
<a name="lambda-managed-instances-metric-frequency"></a>

Lambda 托管实例的指标每 5 分钟发布一次，并会保留 15 个月。

## 查看 CloudWatch 中的指标
<a name="lambda-managed-instances-viewing-metrics"></a>

**要在 CloudWatch 控制台查看 Lambda 托管实例指标**

1. 通过 [console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/) 打开 CloudWatch 控制台。

1. 在导航窗格中，选择**指标**。

1. 在**所有指标**选项卡中，选择 **AWS/Lambda**。

1. 选择要查看的指标维度：
   + 对于容量提供程序级别的指标，请按 **CapacityProviderName** 和 **InstanceType** 进行筛选
   + 对于执行环境级别的指标，请按 **CapacityProviderName**、**FunctionName** 和 **Resource**进行筛选

1. 选择要监控的指标。

## 使用指标优化性能
<a name="lambda-managed-instances-using-metrics"></a>

监控 CPU 和内存利用率，以了解您的函数是否大小得当。高利用率可能意味着需要使用更大的实例类型或者增加函数内存的分配量。跟踪并发指标以了解扩展行为并识别潜在的节流。

监控容量指标，以验证是否有足够的资源可用于工作负载。**vCPUAvailable** 和 **MemoryAvailable** 指标可帮助您了解实例上的剩余容量。

## 后续步骤
<a name="lambda-managed-instances-monitoring-next-steps"></a>
+ 了解有关[扩展 Lambda 托管实例](lambda-managed-instances-scaling.md)的信息
+ 查看 [Java](lambda-managed-instances-java-runtime.md)、[Node.js](lambda-managed-instances-nodejs-runtime.md) 和 [Python](lambda-managed-instances-python-runtime.md) 的运行时特定指南
+ [为您的容量提供程序配置 VPC 连接](lambda-managed-instances-networking.md)
+ 了解 [Lambda 托管实例的安全和权限](lambda-managed-instances-security.md)

# Lambda 托管实例配额
<a name="lambda-managed-instances-quotas"></a>

本页介绍 AWS Lambda 托管实例的服务配额。这些配额与 AWS Lambda（默认）配额是分开的。有些配额可以在请求时增加。

## Lambda API 请求配额
<a name="lambda-managed-instances-api-request-quotas"></a>

这些配额控制着您调用 API 来管理 Lambda 托管实例容量提供程序的速率。读取和写入 API 速率限制适用于所有容量提供程序操作的组合，包括创建、更新、描述和删除容量提供程序。


| 资源 | 限额 | 
| --- | --- | 
| 所有容量提供程序读取 API 的最大组合速率（每秒请求数） | 每秒 15 个请求。无法增加。 | 
| 所有容量提供程序写入 API 的最大组合速率（每秒请求数） | 每秒 1 个请求。无法增加。 | 

## Lambda 托管实例资源配额
<a name="lambda-managed-instances-resource-quotas"></a>

这些配额定义了您的 AWS 账户中核心 Lambda 托管实例资源的限制。它们控制着您能够创建的容量提供程序的数量，以及能与每个容量提供程序关联的函数版本的数量。


| 资源 | 限额 | 
| --- | --- | 
| 容量提供程序 | 1000。一个账户中所能创建的最大容量提供程序数量。 | 
| 每个容量提供程序的函数版本 | 100. 每个容量提供程序的最大函数版本数量。无法增加。 | 

## 事件源映射配额
<a name="lambda-managed-instances-event-source-quotas"></a>

这些配额用于控制在 Lambda 托管实例上处理来自各种 AWS 服务的事件的吞吐量和配置限制。吞吐量限制可确保性能的可预测性，而映射计数限制则有助于维持服务的稳定性。Lambda 托管实例上的事件源映射支持使用 Amazon SQS、DynamoDB Streams、Amazon Kinesis Data Streams、Amazon MSK 和自行管理的 Apache Kafka 作为事件源。


| 资源 | 限额 | 
| --- | --- | 
| Lambda 托管实例上的标准 SQS 事件源映射吞吐量 | 每秒 5MB。无法增加。 | 
| Lambda 托管实例上的标准 Kafka 事件源映射吞吐量 | 每秒 1MB。无法增加。 | 
| Lambda 托管实例上的标准 Kafka 事件源映射 | 100 个事件源映射 无法增加。 | 
| Lambda 托管实例上的 Kinesis 事件源映射吞吐量 | 每秒 25MB。可以增加。 | 
| Lambda 托管实例上的 DynamoDB 事件源映射吞吐量 | 每秒 10MB。可以增加。 | 
| 在 Lambda 托管实例上调用异步调用的请求吞吐量 | 每秒 5MB。可以增加。 | 

## 请求提高限额
<a name="lambda-managed-instances-requesting-quota-increase"></a>

对于可以增加的配额，您可以通过服务配额控制台提出增加的请求。

**要请求提高限额**

1. 通过 [console.aws.amazon.com/servicequotas/](https://console.aws.amazon.com/servicequotas/) 打开服务配额控制台。

1. 在导航窗格中，选择 **AWS 服务**。

1. 选择 **AWS Lambda**。

1. 选择要增加的配额。

1. 选择**请求增加限额**。

1. 输入新的配额值，并提供增加配额的理由。

1. 选择**请求**。

## 后续步骤
<a name="lambda-managed-instances-quotas-next-steps"></a>
+ 了解 [Lambda 托管实例的容量提供程序](lambda-managed-instances-capacity-providers.md)
+ 了解 [Lambda 托管实例的扩展](lambda-managed-instances-scaling.md)
+ 查看 [Java](lambda-managed-instances-java-runtime.md)、[Node.js](lambda-managed-instances-nodejs-runtime.md) 和 [Python](lambda-managed-instances-python-runtime.md) 的运行时特定指南
+ [为您的容量提供程序配置 VPC 连接](lambda-managed-instances-networking.md)

# Lambda 托管实例的最佳实践
<a name="lambda-managed-instances-best-practices"></a>

## 容量提供程序配置
<a name="lambda-managed-instances-bp-capacity-provider"></a>

**按信任级别分离容量提供程序。**为具有不同安全要求的工作负载创建不同的容量提供程序。分配给同一容量提供程序的所有功能必须相互信任，因为容量提供程序充当着安全边界的角色。

**采用描述性名称。**对容量提供程序进行命名，以清楚地表明其预期用途和信任级别（例如 `production-trusted`、`dev-sandbox`）。这有助于团队了解每个容量提供程序的目的和安全状况。

**使用多个可用区。**创建容量提供程序时，指定跨多个可用区的子网。Lambda 默认为可用区启动三个实例以增强韧性，从而确保您的函数具备高可用性。

## 实例类型选择
<a name="lambda-managed-instances-bp-instance-types"></a>

**让 Lambda 选择实例类型。**默认情况下，Lambda 会为您的工作负载选择最佳实例类型。我们建议让 Lambda 托管实例为您选择实例类型，因为限制可能的实例类型数量可能会导致可用性降低。

**根据特定要求指定实例类型。**如果您有特定的硬件要求，请将允许的实例类型设置为兼容的实例列表。例如：
+ 对于需要高网络带宽的应用程序，请选择多种 n 系列实例类型
+ 对于有成本约束的测试或开发环境，请选择较小的实例类型，例如 m7a.large

## 函数配置
<a name="lambda-managed-instances-bp-function-config"></a>

**选择适当的内存和 vCPU 设置。**选择能够支持您的函数多并发执行的内存和 vCPU 配置。支持的最小函数大小为 2GB 和 1 个 vCPU。
+ 对于 Python 应用程序，由于 Python 处理多并发的方式，选择较高的内存与 vCPU 比（例如 4:1 或 8:1）
+ 对于 CPU 密集型操作或执行少量 IO 的函数，请选择多个 vCPU
+ 对于 IO 密集型应用程序（如 Web 服务或批处理作业），多并发可提供最大的益处

**适当配置最大并发。**Lambda 会选择合理的默认值以实现最大的并发性，从而在资源消耗和吞吐量之间达到平衡。根据函数的资源使用情况调整此设置：
+ 如果您的函数调用所占用的 CPU 资源极少，可提高最大并发数（最高每个 vCPU 64 个）
+ 如果您的应用程序占用大量内存但 CPU 使用率很低，请降低最大并发数。

请注意，并发度极低的执行环境可能会出现节流并难以实现扩展。

## 扩展配置
<a name="lambda-managed-instances-bp-scaling"></a>

**设置适当的目标资源利用率。**默认情况下，Lambda 会保留足够的余量，让您的流量在 5 分钟翻倍也不会受到节流。根据您的工作负载特征对此进行调整：
+ 对于非常稳定的工作负载或对节流不敏感的应用程序，将目标设定得较高，以实现更高的利用率和更低的成本。
+ 对于可能出现流量爆发的工作负载，请将资源目标设置为较低水平，以维持额外的余量

**规划流量增长。**如果您的流量在 5 分钟内增长超过一倍，您可能会在 Lambda 纵向扩展实例和执行环境时看到节流出现。请设计您的应用程序，以应对在快速纵向扩展期间可能出现的节流情况。

## 安全性
<a name="lambda-managed-instances-bp-security"></a>

**对 PassCapacityProvider 权限应用最低权限。**仅向必要的容量提供程序授予 `lambda:PassCapacityProvider` 权限。使用资源级权限来限制用户能够为函数分配哪些容量提供程序。

**监控容量提供程序的使用情况。**使用 AWS CloudTrail 监控容量提供程序的分配和访问模式。这有助于识别未经授权的访问行为，并确保符合安全策略的要求。

**隔离不受信任的工作负载。**不要依靠容器来实现不受信任的工作负载之间的安全隔离。使用不同的容量提供程序来隔离相互不信任的工作负载。

## 成本优化
<a name="lambda-managed-instances-bp-cost"></a>

**利用 EC2 定价选项。**利用 EC2 节省计划和预留实例来降低成本。这些定价选项适用于底层 EC2 计算（15% 的管理费不享受折扣）。

**针对稳态工作负载进行优化。**Lambda 托管实例最适合具有稳态特性且流量可预测的大流量函数。对于突发流量模式，Lambda（默认）可能更具成本效益。

**监控资源利用率。**跟踪 CloudWatch 指标以了解 CPU 和内存利用率。根据实际使用模式调整函数内存分配和实例类型选择，以优化成本。

## 监控和可观测性
<a name="lambda-managed-instances-bp-monitoring"></a>

**监控容量提供程序指标。**跟踪容量提供程序级别的指标（包括 CPUUtilization、MemoryUtilization、vCPUAvailable 和 MemoryAvailable），以验证是否有足够的资源可用于工作负载。

**监控执行环境指标。**跟踪执行环境级别的指标，包括 ExecutionEnvironmentConcurrency 和 ExecutionEnvironmentConcurrencyLimit，以了解扩展行为并识别潜在的节流。

**设置 CloudWatch 警报。**为关键指标创建 CloudWatch 警报，以主动识别问题：
+ CPU 或内存利用率高
+ 可用容量低
+ 接近并发限制

## 特定语言注意事项
<a name="lambda-managed-instances-bp-runtime"></a>

**遵循特定语言的最佳实践。**每种编程语言处理多并发的方式不同。请查看特定语言指南，了解详细建议：
+ **Java：**对特定于请求的状态使用线程安全的集合 `AtomicInteger` 和 `ThreadLocal` 
+ **Node.js：**对所有特定于请求的状态使用 InvokeStore，并避免使用全局变量
+ **Python：**在 `/tmp` 中使用包含请求 ID 的唯一文件名，并考虑采用基于进程的内存隔离
+ **Rust：**使用 `run_concurrent` 代替 `run`，启用 `concurrency-tokio` 功能。处理程序必须是 `Clone` \$1 `Send`。

**测试线程安全和并发问题。**在将函数部署到生产环境之前，对您的函数进行全面测试，以检查是否存在线程安全问题、争用条件以及在并发负载下是否能正确实现状态隔离。

## 后续步骤
<a name="lambda-managed-instances-bp-next-steps"></a>
+ 了解 [Lambda 托管实例的容量提供程序](lambda-managed-instances-capacity-providers.md)
+ 了解 [Lambda 托管实例的扩展](lambda-managed-instances-scaling.md)
+ 查看 [Java](lambda-managed-instances-java-runtime.md)、[Node.js](lambda-managed-instances-nodejs-runtime.md) 和 [Python](lambda-managed-instances-python-runtime.md) 的运行时特定指南
+ [为您的容量提供程序配置 VPC 连接](lambda-managed-instances-networking.md)
+ 使用 [CloudWatch 指标](lambda-managed-instances-monitoring.md)监控 Lambda 托管实例

# 排查 Lambda 托管实例问题
<a name="lambda-managed-instances-troubleshooting"></a>

## 节流和扩缩问题
<a name="lambda-managed-instances-ts-throttling"></a>

### 纵向扩展过程中错误率高
<a name="lambda-managed-instances-ts-high-error-rates"></a>

**问题：**当流量迅速增加时，您会遇到节流错误（HTTP 429）。

**原因：**Lambda 托管实例根据 CPU 资源利用率和多并发饱和状态进行异步扩展。如果您的流量在 5 分钟内增长超过一倍，您可能会在 Lambda 纵向扩展实例和执行环境以满足需求时看到节流出现。

**解决方案：**
+ **调整目标资源利用率：**如果您的工作负载具有可预测的流量模式，则应设定较低的目标资源利用率，以便为流量突发留出更多的缓冲空间。
+ **预热容量：**对于计划中的流量增加，请通过较长时间的逐步增加来实现流量的提升，以使扩展保持同步。
+ **监控扩展指标：**跟踪节流错误指标，以了解节流和容量扩展问题的原因。
+ **查看函数配置：**确保您的函数内存和 vCPU 设置支持多并发执行。如果需要，请增加函数内存或 vCPU 分配。

### 减慢缩减
<a name="lambda-managed-instances-ts-slow-scale-down"></a>

**问题：**流量减少后，实例的缩减过程会持续很长时间。

**原因：**Lambda 托管实例会逐渐缩减，以保持可用性并避免可能影响性能的快速容量变化。

**解决方案：**

这是预料之中的行为。Lambda 会谨慎地缩减实例，以确保稳定性。监控您的 CloudWatch 指标，以跟踪正在运行的实例数量。

## 并发问题
<a name="lambda-managed-instances-ts-concurrency"></a>

### 具有低并发性的执行环境会出现节流情况
<a name="lambda-managed-instances-ts-low-concurrency-throttles"></a>

**问题：**尽管有可用容量，但您的函数仍会出现节流情况。

**原因：**具有极低最大并发量的执行环境可能难以实现有效扩展。Lambda 托管实例专为多并发应用程序而设计。

**解决方案：**
+ **提高最大并发数：**如果您的函数调用所占用的 CPU 极少，可提高最大并发数设置至最高每个 vCPU 64 个。
+ **优化函数代码：**查看您的函数代码，以降低每次调用时的 CPU 使用量，从而实现更高的并发性。
+ **调整函数内存和 vCPU：**确保您的函数具备足够的资源来处理多个并发调用。

### 线程安全问题（Java 运行时）
<a name="lambda-managed-instances-ts-thread-safety-java"></a>

**问题：**您的 Java 函数生成错误的结果或在负载下遭遇竞争条件。

**原因：**多个线程同时执行处理程序方法，且共享状态不具有线程安全性。

**解决方案：**
+ 使用 `AtomicInteger` 或 `AtomicLong` 替代基元类型作为计数器
+ 将 `HashMap` 替换为 `ConcurrentHashMap`
+ 使用 `Collections.synchronizedList()` 来包装 `ArrayList`
+ 将 `ThreadLocal` 用于特定于请求的状态
+ 从 Lambda 上下文对象访问跟踪 ID，而不是环境变量

有关详细指导，请参阅 [Lambda 托管实例的 Java 运行时](lambda-managed-instances-java-runtime.md)文档。

### 状态隔离问题（Node.js 运行时）
<a name="lambda-managed-instances-ts-state-isolation-nodejs"></a>

**问题：**您的 Node.js 函数会从不同的请求中返回数据，或者会出现数据损坏的情况。

**原因：**全局变量在同一工作线程的并发调用中被共享。当异步操作释放控制权时，其他调用可以修改共享状态。

**解决方案：**
+ 安装并将 `@aws/lambda-invoke-store` 用于所有特定于请求的状态
+ 将全局变量替换为 `InvokeStore.set()` 和 `InvokeStore.get()`
+ 在 `/tmp` 中使用带有请求 ID 的唯一文件名
+ 使用 `InvokeStore.getXRayTraceId()` 访问跟踪 ID，而不是环境变量

有关详细指导，请参阅 [Lambda 托管实例的 Node.js 运行时](lambda-managed-instances-nodejs-runtime.md)文档。

### 文件冲突（Python 运行时）
<a name="lambda-managed-instances-ts-file-conflicts-python"></a>

**问题：**您的 Python 函数从 `/tmp` 中的文件中读取了错误的数据。

**原因：**多个进程共享 `/tmp` 目录。对同一文件进行并发写入操作可能会导致数据损坏。

**解决方案：**
+ 使用带有请求 ID 的唯一文件名：`/tmp/request_{context.request_id}.txt`
+ 将文件锁定与 `fcntl.flock()` 结合用于共享文件
+ 在使用后通过 `os.remove()` 清理临时文件

有关详细指导，请参阅 [Lambda 托管实例的 Python 运行时](lambda-managed-instances-python-runtime.md)文档。

## 性能问题
<a name="lambda-managed-instances-ts-performance"></a>

### 高内存利用率
<a name="lambda-managed-instances-ts-high-memory"></a>

**问题：**您的函数出现内存使用率过高或内存不足的问题。

**原因：**Python 中的每个并发请求都在单独的进程中运行，且拥有自己的内存空间。总内存使用量等于每个进程的内存占用量乘以并发进程数量。

**解决方案：**
+ 在 CloudWatch 中监控 `MemoryUtilization` 指标
+ 如果内存使用量接近函数的内存限制，请降低 `MaxConcurrency` 设置
+ 增加函数内存分配以支持更高的并发数
+ 通过按需加载数据而非在初始化时加载来优化内存使用情况

### 不一致的性能
<a name="lambda-managed-instances-ts-inconsistent-performance"></a>

**问题：**函数性能在不同的调用之间差异很大。

**原因：**Lambda 可能会根据可用性选择不同的实例类型，或者某些函数可能运行在资源可用性各不相同的实例上。

**解决方案：**
+ **指定允许的实例类型：**如果您有特定的性能要求，请在容量提供程序中配置允许的实例类型，以限制 Lambda 可选择的实例类型。
+ **监控实例级别的指标：**在容量提供程序级别进行跟踪 `CPUUtilization` 和 `MemoryUtilization` 以确定资源限制。
+ **查看容量指标：**检查 `vCPUAvailable` 和 `MemoryAvailable` 以确保您的实例上有足够的可用资源。

## 容量提供程序问题
<a name="lambda-managed-instances-ts-capacity-provider"></a>

### 函数版本未能变为 ACTIVE 状态
<a name="lambda-managed-instances-ts-function-not-active"></a>

**问题：**您的函数版本发布后仍处于待处理状态。

**原因：**Lambda 正在启动托管实例并开启执行环境。此过程需要时间，特别是对于新容量提供程序上的第一个函数版本。

**解决方案：**

等待 Lambda 完成初始化过程。默认情况下，Lambda 会启动三个实例以实现可用区的容错功能，并在将您的函数版本标记为 ACTIVE 之前启动三个执行环境。这通常需要几分钟时间。

### 无法删除容量提供程序
<a name="lambda-managed-instances-ts-cannot-delete"></a>

**问题：**您在尝试删除容量提供程序时收到错误。

**原因：**您无法删除已附加了函数版本的容量提供程序。

**解决方案：**

1. 使用 `ListFunctionVersionsByCapacityProvider` API 识别所有使用该容量提供程序的函数版本。

1. 删除或更新这些函数版本，以解除容量提供程序的关联。

1. 重新尝试删除容量提供程序。

### 发布函数过程中出现的一般错误消息
<a name="lambda-managed-instances-ts-generic-errors"></a>

**问题：**发布函数时，您会遇到一般错误消息，例如“发布期间出现内部错误”。

**解决方案：**
+ **检查 IAM 权限：**确保您对尝试使用的容量提供程序拥有 `lambda:PassCapacityProvider` 权限。
+ **验证容量提供程序配置：**使用 `GetCapacityProvider` API 确认您的容量提供程序处于 ACTIVE 状态。
+ **查看 VPC 配置：**确保您的容量提供程序中指定的子网和安全组配置正确且可访问。
+ **检查 AWS CloudTrail 日志：**查看 CloudTrail 日志，了解有关失败操作的详细错误信息。

## 监控和可观测性问题
<a name="lambda-managed-instances-ts-monitoring"></a>

### CloudWatch 指标缺失
<a name="lambda-managed-instances-ts-missing-metrics"></a>

**问题：**您在 CloudWatch 中无法看到您的容量提供程序或函数所对应的预期指标。

**原因：**这些指标每隔 5 分钟发布一次。新的容量提供程序或函数可能无法立即提供指标。

**解决方案：**

发布函数版本后，至少等待 5 到 10 分钟，然后才能期望在 CloudWatch 中看到相关指标。请确认您查看的命名空间（`AWS/Lambda`）和维度（`CapacityProviderName`、`FunctionName` 或 `InstanceType`）是否正确。

### 找不到 CloudWatch 日志
<a name="lambda-managed-instances-ts-no-logs"></a>

**问题：**您的函数成功执行，但在 CloudWatch Logs 中找不到相关日志。

**原因：**Lambda 托管实例在您的 VPC 中运行，需要网络连接才能将日志发送至 CloudWatch Logs。如果没有正确的 VPC 连接配置，您的函数将无法连接到 CloudWatch Logs 服务端点。

**解决方案：**

配置 VPC 连接来让您的函数将日志发送到 CloudWatch Logs。您有三种选择：

**选项 1：CloudWatch Logs 的 VPC 端点（建议用于生产环境）**

1. 通过 [console.aws.amazon.com/vpc/](https://console.aws.amazon.com/vpc/) 打开 Amazon VPC 控制台。

1. 在导航窗格中，选择**端点**。

1. 选择 **创建端点**。

1. 对于**服务类别**，选择 **AWS 服务**。

1. 在**服务名称**中，选择 `com.amazonaws.region.logs`（将 `region` 替换为您的 AWS 区域）。

1. 对于 **VPC**，请选择您的容量提供程序使用的 VPC。

1. 对于**子网**，选择要在其中创建端点网络接口的子网。要获得高可用性，在多个可用区中选择子网。

1. 对于**安全组**，请选择允许来自您函数安全组的入站 HTTPS 流量（端口 443）的安全组。

1. 为端点启用**私有 DNS**。

1. 选择**创建端点**。

**选项 2：带有互联网网关的公有子网**

如果您的容量提供程序使用公有子网，请确保：

1. 互联网网关已连接到您的 VPC

1. 路由表将 `0.0.0.0/0` 流量路由到互联网网关

1. 安全组允许端口 443 上的出站 HTTPS 流量

**选项 3：具有 NAT 网关的私有子网**

如果您的容量提供程序使用私有子网，请确保：

1. 公有子网中存在 NAT 网关

1. 私有子网路由表将 `0.0.0.0/0` 流量路由到 NAT 网关

1. 公有子网路由表将 `0.0.0.0/0` 流量路由到互联网网关

1. 安全组允许端口 443 上的出站 HTTPS 流量

有关 VPC 连接选项的详细指南，请参阅 [Lambda 托管实例的 VPC 连接](lambda-managed-instances-networking.md)。

### 难以将来自并发请求的日志进行关联
<a name="lambda-managed-instances-ts-log-correlation"></a>

**问题：**来自不同请求的日志是交错排列的，这使得难以跟踪具体的单个请求。

**原因：**在多并发系统中，日志的交错排列是预期且标准的行为。

**解决方案：**
+ **使用采用 JSON 格式的结构化日志记录：**在所有日志语句中包含请求 ID
+ **Java：**将 Log4j 与 `ThreadContext` 配合使用以自动包含请求 ID
+ **Node.js：**使用采用 JSON 格式的 `console.log()` 并包含 `InvokeStore.getRequestId()`
+ **Python：**使用采用 JSON 格式的标准日志记录模块并包含 `context.request_id`

有关详细指导，请参阅特定于运行时的文档页面。

## 获得更多帮助
<a name="lambda-managed-instances-ts-getting-help"></a>

如果您在尝试这些解决方案后仍然遇到问题：

1. **查看 CloudWatch 指标：**检查容量提供程序和执行环境指标，以确定资源限制或扩展问题。

1. **检查 AWS CloudTrail 日志：**查看 CloudTrail 日志，了解有关 API 调用和错误的详细错误信息。

1. **联系 AWS Support：**如果您无法解决问题，请联系 AWS Support，提供有关您的容量提供程序配置、函数配置以及您遇到的具体错误消息的详细信息。

## 后续步骤
<a name="lambda-managed-instances-ts-next-steps"></a>
+ 了解 [Lambda 托管实例的容量提供程序](lambda-managed-instances-capacity-providers.md)
+ 了解 [Lambda 托管实例的扩展](lambda-managed-instances-scaling.md)
+ 查看 [Java](lambda-managed-instances-java-runtime.md)、[Node.js](lambda-managed-instances-nodejs-runtime.md) 和 [Python](lambda-managed-instances-python-runtime.md) 的运行时特定指南
+ 使用 [CloudWatch 指标](lambda-managed-instances-monitoring.md)监控 Lambda 托管实例
+ 查看 [Lambda 托管实例的最佳实践](lambda-managed-instances-best-practices.md)