Rust 对 Lambda 托管实例的支持 - AWS Lambda

Rust 对 Lambda 托管实例的支持

并发配置

Lambda 向每个执行环境发送的最大并发请求数由函数配置中的 PerExecutionEnvironmentMaxConcurrency 设置控制。这是一个可选设置,Rust 的默认设置为每个 vCPU 8 个并发请求,您也可以自行配置其他数值。该值决定运行时产生的 Tokio 任务数量,在执行环境的生命周期内保持不变。每个工作线程一次仅处理一个进行中的请求,且每个工作线程不存在多路复用。Lambda 会根据每个执行环境吸收这些请求的容量,自动调整并发请求的数量,最高到配置的最大值。

为多并发构建函数

在使用 Lambda 托管实例时,您应像在任何其他多线程环境中一样,采用相同的线程安全措施。由于处理程序对象在所有工作线程中是共享的,因此任何可变状态都必须是线程安全的。这包括集合、数据库连接以及在请求处理过程中被修改的任何静态对象。

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

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

lambda_runtime::run_concurrent(…) 入口点必须在 Tokio 运行时中调用,通常由主函数的 #[tokio::main] 属性提供。您的处理程序闭包必须实现 Clone+ Send。这允许框架在多个异步任务中安全地共享处理程序。如果未满足这些限制,则不会编译您的代码。

当您需要在多次调用之间共享状态(例如数据库连接池、配置结构体)时,请将其封装在 Arc 中,并将 Arc 克隆到每次调用中。

所有 Rust 客户端的 AWS SDK 都是并发安全的,不需要特殊处理。

示例:AWS SDK 客户端

以下示例使用 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

示例:数据库连接池

当您的处理程序需要访问共享状态(例如客户端和配置)时,请将其封装在 Arc 中,并将 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 目录

/tmp 目录在执行环境中为所有并发调用共享使用。每次调用使用唯一的文档名(如包含请求 ID)或实施显式文档锁定,以避免数据损坏。

日志记录

在多并发系统中,日志交错(即来自不同请求的日志条目在日志中交错排列)是常见现象。通过 Lambda 的高级日志控制,使用 Lambda 托管实例的函数支持结构化 JSON 日志格式。此格式包括 requestId,使得日志条目能够与单个请求相关联。有关更多信息,请参阅 使用 Tracing crate 实现高级日志记录

请求上下文

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 检测超时 — 它包含以毫秒为单位的调用截止日期。

初始化和关闭

函数初始化会在每个执行环境中发生一次。初始化期间创建的对象在请求之间共享。

对于带有扩展程序的 Lambda 函数,其执行环境在关闭时会发出一个 SIGTERM 信号。扩展程序使用此信号来触发清理任务,例如刷新缓冲区。 lambda_runtime 提供了一个辅助工具来简化优雅关闭信号处理的配置,即 spawn_graceful_shutdown_handler()。要了解有关执行环境生命周期的更多信息,请参阅 了解 Lambda 执行环境生命周期

依赖项版本

Lambda 托管实例需要以下最低程序包版本:

  • lambda_runtime: 版本 1.1.1 或更高版本,已启用 concurrency-tokio 功能

  • 支持的最低 Rust 版本 (MSRV) 为 1.84.0。