

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