Tiempo de ejecución de .NET para instancias administradas de Lambda - AWS Lambda

Tiempo de ejecución de .NET para instancias administradas de Lambda

Para los tiempos de ejecución de .NET, las instancias administradas de Lambda utilizan un único proceso .NET por entorno de ejecución. Se procesan varias solicitudes simultáneas mediante las tareas de .NET.

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. Se trata de una configuración opcional y el valor predeterminado varía en función del tiempo de ejecución. Para los tiempos de ejecución de .NET, el valor predeterminado es de 32 solicitudes simultáneas por vCPU, o puede configurar su propio valor. 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 concurrencia cuando utilice instancias administradas de Lambda que en cualquier otro entorno de concurrencia múltiple. Como el objeto controlador se comparte entre todas las tareas, 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.

Los clientes de AWS SDK son seguros para subprocesos y no requieren una gestión especial.

Ejemplo: grupos de conexiones a bases de datos

El código siguiente utiliza un objeto de conexión de base de datos estático que se comparte entre solicitudes simultáneas. El objeto SqlConnection no es seguro para los subprocesos.

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(); ... } }

Para solucionar este problema, use una conexión independiente para cada solicitud, extraída de un grupo de conexiones. Los proveedores de ADO.NET, por ejemplo Microsoft.Data.SqlClient, admiten automáticamente la agrupación de conexiones cuando se abre el objeto de conexión.

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(); ... } }

Ejemplo: colecciones

Las recopilaciones estándar de .NET no son seguras para los subprocesos:

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"; } }

Utilice colecciones del espacio de nombres de System.Collections.Concurrent para garantizar la seguridad de la concurrencia:

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"; } }

Directorio /tmp compartido

El directorio /tmp se comparte entre todas las solicitudes simultáneas del entorno de ejecución. Las escrituras simultáneas en el mismo archivo pueden dañar los datos, por ejemplo, si otra solicitud sobrescribe el archivo. Para solucionar este problema, implemente el bloqueo de archivos para los archivos compartidos o utilice nombres de archivo únicos por solicitud para evitar conflictos. Recuerde limpiar los archivos innecesarios para no agotar el espacio disponible.

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 utilizan siempre el formato de registro JSON estructurado introducido con los controles de registro avanzados. Este formato incluye el requestId, lo que permite correlacionar las entradas de registro con una sola solicitud. Cuando utiliza el objeto context.Logger para generar registros, el requestId se incluye automáticamente en cada entrada de registro. Para obtener más información, consulte Uso de los controles de registro avanzados de Lambda con .NET.

El contexto de la solicitud

Utilice la propiedad context.AwsRequestId para acceder al identificador de solicitud de la solicitud actual.

Utilice la propiedad context.TraceId para acceder al identificador de seguimiento de X-Ray. Esto proporciona un acceso simultáneo y seguro al identificador de seguimiento de la solicitud actual. 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 AWS SDK.

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 para desencadenar tareas de limpieza, como vaciar los búferes. Puede suscribirse a los eventos SIGTERM para desencadenar tareas de limpieza de funciones, como cerrar las conexiones a las bases de datos. Para obtener más información sobre el ciclo de vida del entorno de ejecución, consulte Descripción del ciclo de vida del entorno de ejecución de Lambda.

Versiones de dependencias

Las instancias administradas de Lambda requieren las siguientes versiones de paquete como mínimo:

  • Amazon.Lambda.Core: versión 2.7.1 o posterior

  • Amazon.Lambda.RuntimeSupport: versión 1.14.1 o posterior

  • OpenTelemetry.Instrumentation.AWSLambda: versión 1.14.0 o posterior

  • AWSXRayRecorder.Core: versión 2.16.0 o posterior

  • AWSSDK.Core: versión 4.0.0.32 o posterior

Powertools para AWS Lambda (.NET)

Powertools para AWS Lambda (.NET) y AWS Distro para OpenTelemetry: la instrumentación para DotNet actualmente no admite instancias administradas de Lambda.

Siguientes pasos