Compatibilidad de Rust con instancias administradas de Lambda - AWS Lambda

Compatibilidad de Rust con instancias administradas de Lambda

Configuración de concurrencia

El número máximo de solicitudes simultáneas que envía Lambda a cada entorno de ejecución se controla mediante el ajuste PerExecutionEnvironmentMaxConcurrency de la configuración de la función. Esta es una configuración opcional y el valor predeterminado para Rust es de 8 solicitudes simultáneas por vCPU; también puede configurar su propio valor. Este valor determina la cantidad de tareas de Tokio que genera el tiempo de ejecución y permanece fijo durante toda la vida útil del entorno de ejecución. Cada proceso de trabajo gestiona exactamente una solicitud en curso a la vez, sin multiplexación por proceso de trabajo. Lambda ajusta automáticamente el número de solicitudes simultáneas hasta el máximo configurado en función de la capacidad de cada entorno de ejecución para absorber esas solicitudes.

Creación de funciones para la concurrencia múltiple

Debe aplicar las mismas prácticas de seguridad de subprocesos cuando utilice instancias administradas de Lambda que en cualquier otro entorno de subprocesos múltiples. Como el objeto controlador se comparte entre todos los subprocesos de trabajo, cualquier estado mutable debe ser seguro para subprocesos. Esto incluye las colecciones, las conexiones a bases de datos y cualquier objeto estático que se modifique durante el procesamiento de la solicitud.

Para habilitar el manejo de solicitudes simultáneas, agregue la marca de la característica concurrency-tokio a su archivo Cargo.toml.

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

El punto de entrada lambda_runtime::run_concurrent(…) debe llamarse dentro de un tiempo de ejecución de Tokio, que normalmente se proporciona mediante el atributo #[tokio::main] en su función principal. El cierre de su controlador debe implementar Clone + Send. Esto permite que el marco de trabajo comparta el controlador entre varias tareas asíncronas de forma segura. Si no se cumplen esos límites, su código no se compilará.

Cuando necesite estado compartido en el código entre invocaciones (un grupo de conexiones a base de datos, una estructura de configuración), encapsúlelo en Arc y clone el Arc en cada invocación.

Todos los clientes del SDK AWS para Rust son seguros para la concurrencia y no requieren un manejo especial.

Ejemplo: cliente del SDK AWS

En el siguiente ejemplo, se utiliza un cliente de S3 para cargar un objeto en cada invocación. El cliente se clona directamente en el cierre sin 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

Ejemplo: grupos de conexiones a bases de datos

Cuando el controlador necesita acceder a estado compartido, como un cliente y una configuración, encapsúlelo en Arc y clone el Arc en cada invocación.

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

Directorio /tmp compartido

El directorio /tmp se comparte entre todas las invocaciones simultáneas en el mismo entorno de ejecución. Utilice nombres de archivo únicos por invocación (por ejemplo, incluya el identificador de solicitud) o implemente un bloqueo de archivos explícito para evitar la corrupción de datos.

Registro

El intercalado de registros (las entradas de registro de diferentes solicitudes se intercalan en los registros) es normal en los sistemas simultáneos múltiples. Las funciones que utilizan instancias administradas de Lambda admiten el formato de registro JSON estructurado mediante los controles de registro avanzados de Lambda. Este formato incluye el requestId, lo que permite correlacionar las entradas de registro con una sola solicitud. Para obtener información adicional, consulte Implementación del registro avanzado con la caja Tracing.

Contexto de la solicitud

El objeto Context se pasa directamente a cada invocación del controlador. Utilice event.context.request_id para acceder al identificador de solicitud de la solicitud actual.

Utilice el event.context.xray_trace_id para acceder al identificador de seguimiento de X-Ray. Lambda no admite la variable de entorno _X_AMZN_TRACE_ID con las instancias administradas de Lambda. El identificador de seguimiento de X-Ray se propaga automáticamente cuando se utiliza el SDK AWS para Rust.

Utilice event.context.deadline para detectar tiempos de espera: contiene el plazo de la invocación en milisegundos.

Inicialización y apagado

La inicialización de la función se produce una vez por entorno de ejecución. Los objetos creados durante la inicialización se comparten entre las solicitudes.

En el caso de las funciones de Lambda con extensiones, el entorno de ejecución emite una señal SIGTERM durante el cierre. Las extensiones utilizan esta señal ppara activar tareas de limpieza, como el vaciado de búferes. lambda_runtime ofrece una función auxiliar para simplificar la configuración del manejo del apagado ordenado de señales, spawn_graceful_shutdown_handler(). Para obtener más información sobre el ciclo de vida del entorno de ejecución, consulte Comprender el ciclo de vida del entorno de ejecución de Lambda.

Versiones de dependencias

Las instancias administradas de Lambda requieren la siguiente versión de paquete como mínimo:

  • lambda_runtime: versión 1.1.1 o posterior, con la característica concurrency-tokio habilitada

  • La versión mínima compatible de Rust (MSRV) es la 1.84.0.