

# Tiempos de ejecución de instancias administradas de Lambda
<a name="lambda-managed-instances-runtimes"></a>

Lambda procesa las solicitudes de forma diferente cuando se utilizan instancias administradas de Lambda. En lugar de gestionar las solicitudes en cada entorno de ejecución de forma secuencial, las instancias administradas de Lambda procesan varias solicitudes de forma simultánea en cada entorno de ejecución. Este cambio en el modelo de ejecución significa que las funciones que utilizan instancias administradas de Lambda deben tener en cuenta la seguridad de los subprocesos, la administración del estado y el aislamiento del contexto, problemas que no surgen en el modelo de concurrencia única de Lambda (predeterminado). Además, la implementación de concurrencia múltiple varía según los tiempos de ejecución.

## Lenguajes admitidos
<a name="lambda-managed-instances-supported-runtimes"></a>

Las instancias administradas de Lambda se pueden usar con los siguientes lenguajes de programación y tiempos de ejecución:
+ **Java:** Java 21 y versiones posteriores.
+ **Python:** Python 3.13 y versiones posteriores.
+ **Node.js:** Node.js 22 y versiones posteriores.
+ **.NET:** .NET 8 y versiones posteriores.
+ **Rust:** compatible con el tiempo de ejecución solo del sistema operativo `provided.al2023` y versiones posteriores.

## Consideraciones específicas del lenguaje
<a name="lambda-managed-instances-runtime-considerations"></a>

Cada lenguaje de programación implementa la concurrencia múltiple de forma diferente. Debe comprender cómo se implementa la concurrencia múltiple en el lenguaje de programación que elija para aplicar las mejores prácticas de concurrencia adecuadas.

**Java**

Utiliza un único proceso con subprocesos del sistema operativo para la concurrencia. Varios subprocesos ejecutan el método del controlador simultáneamente, lo que requiere una gestión segura de los recursos compartidos.

**Python**

Utiliza varios procesos de Python en los que cada solicitud simultánea se ejecuta en un proceso independiente. Esto protege contra la mayoría de los problemas de concurrencia, aunque hay que ejercer precaución con los recursos compartidos, como el directorio `/tmp`.

**Node.js**

Utiliza [subprocesos de trabajo](https://nodejs.org/api/worker_threads.html) con ejecución asíncrona. Las solicitudes simultáneas se distribuyen entre los subprocesos de trabajo, y cada subproceso de trabajo también puede gestionar las solicitudes simultáneas de forma asíncrona, lo que requiere una gestión segura de los recursos compartidos y del estado.

**.NET**

Utiliza tareas de .NET con procesamiento asíncrono de varias solicitudes simultáneas. Requiere una gestión segura de los recursos compartidos y del estado.

**Rust**

Utiliza un único proceso con tareas asíncronas impulsadas por [Tokio](https://tokio.rs/). El controlador debe ser `Clone` \$1 `Send`.

## Siguientes pasos
<a name="lambda-managed-instances-runtime-next-steps"></a>

Para obtener información detallada sobre cada tiempo de ejecución, consulte los siguientes temas:
+ [Tiempo de ejecución de Java para instancias administradas de Lambda](lambda-managed-instances-java-runtime.md)
+ [Tiempo de ejecución de Node.js para instancias administradas de Lambda](lambda-managed-instances-nodejs-runtime.md)
+ [Tiempo de ejecución de Python para instancias administradas de Lambda](lambda-managed-instances-python-runtime.md)
+ [Tiempo de ejecución de .NET para instancias administradas de Lambda](lambda-managed-instances-dotnet-runtime.md)
+ [Compatibilidad de Rust con instancias administradas de Lambda](lambda-managed-instances-rust.md)

# Tiempo de ejecución de Java para instancias administradas de Lambda
<a name="lambda-managed-instances-java-runtime"></a>

En el caso de los tiempos de ejecución de Java, las instancias administradas de Lambda utilizan subprocesos del sistema operativo para la concurrencia. Lambda carga el objeto controlador una vez por entorno de ejecución durante la inicialización y, a continuación, crea varios subprocesos. Estos subprocesos se ejecutan en paralelo y requieren una gestión segura de subprocesos de los recursos compartidos y los estados. Cada subproceso comparte el mismo objeto controlador y todos los campos estáticos.

## Configuración de concurrencia
<a name="lambda-managed-instances-java-concurrency-config"></a>

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 Java, el valor predeterminado es de 32 solicitudes simultáneas por vCPU, o puede configurar su propio valor. Este valor también determina el número de subprocesos utilizados por el tiempo de ejecución de Java. 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
<a name="lambda-managed-instances-java-building"></a>

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 en tiempo de ejecución, 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 subprocesos. Según la biblioteca de conexiones utilizada, es posible que no sea segura para subprocesos.

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

Un enfoque seguro para subprocesos consiste en utilizar un grupo de conexiones. En el siguiente ejemplo, el controlador de funciones recupera una conexión del grupo. La conexión solo se utiliza en el contexto de una única solicitud.

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

**Ejemplo: colecciones**

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

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

En su lugar, utilice colecciones seguras para subprocesos:

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

## Directorio /tmp compartido
<a name="lambda-managed-instances-java-shared-tmp"></a>

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 otro proceso sobrescribe el archivo. Para solucionar este problema, implemente el bloqueo de archivos para los archivos compartidos o utilice nombres de archivo únicos por subproceso o por solicitud para evitar conflictos. Recuerde limpiar los archivos innecesarios para no agotar el espacio disponible.

## Registro
<a name="lambda-managed-instances-java-logging"></a>

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](monitoring-logs.md#monitoring-cloudwatchlogs-advanced). Este formato incluye el `requestId`, lo que permite correlacionar las entradas de registro con una sola solicitud. Cuando utiliza el objeto `LambdaLogger` de `context.getLogger()`, el `requestId` se incluye automáticamente en cada entrada de registro. Para obtener información adicional, consulte [Uso de los controles de registro avanzados de Lambda con Java](java-logging.md#java-logging-advanced).

## El contexto de la solicitud
<a name="lambda-managed-instances-java-request-context"></a>

El objeto `context` está enlazado al subproceso de solicitud. El uso de `context.getAwsRequestId()` proporciona un acceso seguro para subprocesos al identificador de solicitud de la solicitud actual.

Utilice el `context.getXrayTraceId()` para acceder al identificador de seguimiento de X-Ray. Esto proporciona un acceso seguro para subprocesos 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.

Utilice `com.amazonaws.services.lambda.runtime.Context.getRemainingTimeInMillis()` para detectar tiempos de espera. Para obtener más información, consulte [Gestión de errores y recuperación](lambda-managed-instances-execution-environment.md#lambda-managed-instances-error-handling).

Si utiliza subprocesos virtuales en su programa o crea subprocesos durante la inicialización, tendrá que pasar cualquier contexto de solicitud necesario a estos subprocesos.

## Inicialización y apagado
<a name="lambda-managed-instances-java-init-shutdown"></a>

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 los subprocesos.

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 [Comprender el ciclo de vida del entorno de ejecución de Lambda](lambda-runtime-environment.md).

## Versiones de dependencias
<a name="lambda-managed-instances-java-dependencies"></a>

Las instancias administradas de Lambda requieren las siguientes versiones de paquete como mínimo:
+ AWS SDK para Java 2.0: versión 2.34.0 o posterior
+ AWS X-Ray SDK para Java: versión 2.20.0 o posterior
+ AWS Distro para OpenTelemetry, instrumentación para Java: versión 2.20.0 o posterior
+ Powertools para AWS Lambda (Java): versión 2.8.0 o posterior

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

Powertools para AWS Lambda (Java) es compatible con las instancias administradas de Lambda y proporciona utilidades para el registro, el seguimiento, las métricas y mucho más. Para obtener más información, consulte [Powertools para AWS Lambda (Java)](https://github.com/aws-powertools/powertools-lambda-java).

## Siguientes pasos
<a name="lambda-managed-instances-java-next-steps"></a>
+ Revise el [tiempo de ejecución de Node.js para instancias administradas de Lambda](lambda-managed-instances-nodejs-runtime.md).
+ Revise el [tiempo de ejecución de Python para instancias administradas de Lambda](lambda-managed-instances-python-runtime.md).
+ Revise el [tiempo de ejecución de .NET para instancias administradas de Lambda](lambda-managed-instances-dotnet-runtime.md).
+ Obtenga información sobre el [escalado de instancias administradas de Lambda](lambda-managed-instances-scaling.md).

# Tiempo de ejecución de Node.js para instancias administradas de Lambda
<a name="lambda-managed-instances-nodejs-runtime"></a>

Para los tiempos de ejecución de Node.js, las instancias administradas de Lambda utilizan subprocesos de trabajo con ejecución basada en `async` o en `await` para gestionar las solicitudes simultáneas. La inicialización de la función se produce una vez por subproceso de trabajo. Las invocaciones simultáneas se gestionan en dos dimensiones: los subprocesos de trabajo proporcionan paralelismo entre las vCPU y la ejecución asíncrona proporciona concurrencia dentro de cada subproceso. Cada solicitud simultánea administrada por el mismo subproceso de trabajo comparte el mismo objeto controlador y el mismo estado global, por lo que es necesaria una gestión segura en el caso de varias solicitudes simultáneas.

## Simultaneidad máxima
<a name="lambda-managed-instances-nodejs-max-concurrency"></a>

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 Node.js, el valor predeterminado es de 64 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.

En el caso de Node.js, el número de solicitudes simultáneas que puede procesar cada entorno de ejecución viene determinado por el número de subprocesos de trabajo y la capacidad de cada subproceso de trabajo para procesar solicitudes simultáneas de forma asíncrona. El número predeterminado de subprocesos de trabajo viene determinado por la cantidad de vCPU disponibles, o puede configurar la cantidad de subprocesos de trabajo configurando la variable de entorno `AWS_LAMBDA_NODEJS_WORKER_COUNT`. Recomendamos utilizar controladores de funciones asíncronos, ya que permiten procesar varias solicitudes por subproceso de trabajo. Si su controlador de funciones es sincrónico, cada subproceso de trabajo solo puede procesar una solicitud a la vez.

## Creación de funciones para la concurrencia múltiple
<a name="lambda-managed-instances-nodejs-building"></a>

Con un controlador de funciones asíncrono, cada trabajador en tiempo de ejecución procesa varias solicitudes de forma simultánea. Los objetos globales se compartirán en varias solicitudes simultáneas. En el caso de los objetos mutables, evite usar el estado global o utilice el `AsyncLocalStorage`.

Los clientes de AWS SDK son seguros para la modalidad asíncrona y no requieren una gestión especial.

**Ejemplo: estado global**

El siguiente código usa un objeto global que está mutado dentro del controlador de funciones. Esto no es seguro para el proceso de forma asíncrona.

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

La inicialización del objeto `state` dentro del controlador de funciones evita un estado global compartido.

```
export const handler = async (event, context) => {
    let state = {
        currentUser: event.userId,
        requestData: event.data
    };
    
    await processData(state.requestData);

    return { user: state.currentUser };
};
```

**Ejemplo: conexiones a bases de datos**

El código siguiente utiliza un objeto de cliente compartido que se comparte entre varias invocaciones. Según la biblioteca de conexiones utilizada, es posible que no sea segura para la concurrencia.

```
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])
  };
};
```

Un enfoque seguro para la concurrencia consiste en utilizar un grupo de conexiones. El grupo utiliza una conexión independiente para cada consulta simultánea de la base de datos.

```
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])
  };
};
```

## Controladores de Node.js 22 basados en la devolución de llamada
<a name="lambda-managed-instances-nodejs-callback-handlers"></a>

Cuando utiliza Node.js 22, no puede usar un controlador de funciones basado en la devolución de llamada con instancias administradas de Lambda. Los controladores basados en la devolución de llamada son compatibles solo con las funciones de Lambda (predeterminadas). Para los tiempos de ejecución de Node.js 24 y versiones posteriores, los controladores de funciones basados en la devolución de llamada están obsoletos, tanto para Lambda (predeterminado) como para las instancias administradas de Lambda.

En su lugar, utilice un controlador de funciones `async` cuando utilice instancias administradas de Lambda. Para obtener más información, consulte [Definición de controlador de funciones de Lambda en Node.js](https://docs.aws.amazon.com/lambda/latest/dg/nodejs-handler.html).

## Directorio /tmp compartido
<a name="lambda-managed-instances-nodejs-shared-tmp"></a>

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 otro proceso 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
<a name="lambda-managed-instances-nodejs-logging"></a>

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](monitoring-logs.md#monitoring-cloudwatchlogs-advanced). Este formato incluye el `requestId`, lo que permite correlacionar las entradas de registro con una sola solicitud. Cuando utiliza el registrador de la `console`, el `requestId` se incluye automáticamente en cada entrada de registro. Para obtener información adicional, consulte [Uso de controles de registro avanzados de Lambda con Node.js](nodejs-logging.md#node-js-logging-advanced).

Las bibliotecas de registro populares de terceros, como [Winston](https://github.com/winstonjs/winston), normalmente incluyen la compatibilidad con el uso de la consola para la salida del registro.

## El contexto de la solicitud
<a name="lambda-managed-instances-nodejs-request-context"></a>

El uso del `context.awsRequestId` proporciona un acceso asíncrono y seguro al identificador de solicitud de la solicitud actual.

Utilice el `context.xRayTraceId` 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.

Utilice `context.getRemainingTimeInMillis()` para detectar tiempos de espera. Para obtener más información, consulte [Gestión de errores y recuperación](lambda-managed-instances-execution-environment.md#lambda-managed-instances-error-handling).

## Inicialización y apagado
<a name="lambda-managed-instances-nodejs-init-shutdown"></a>

La inicialización de la función se produce una vez por subproceso de trabajo. Es posible que vea entradas de registro repetidas si su función emite registros durante la inicialización.

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. Las funciones de Lambda (predeterminadas) con extensiones también pueden suscribirse a la señal SIGTERM mediante `process.on()`. Esto no se admite para las funciones que utilizan instancias administradas de Lambda, ya que no se puede utilizar el `process.on()` con subprocesos de trabajo. 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](lambda-runtime-environment.md).

## Versiones de dependencias
<a name="lambda-managed-instances-nodejs-dependencies"></a>

Las instancias administradas de Lambda requieren las siguientes versiones de paquete como mínimo:
+ AWS SDK para JavaScript v3: versión 3.933.0 o posterior
+ AWS X-Ray SDK para Node.js: versión 3.12.0 o posterior
+ AWS Distro para OpenTelemetry, instrumentación para JavaScript: versión 0.8.0 o posterior
+ Powertools para AWS Lambda (TypeScript): versión 2.29.0 o posterior

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

Powertools para AWS Lambda (TypeScript) es compatible con las instancias administradas de Lambda y proporciona utilidades para el registro, el seguimiento, las métricas y mucho más. Para obtener más información, consulte [Powertools para AWS Lambda (TypeScript)](https://github.com/aws-powertools/powertools-lambda-typescript).

## Siguientes pasos
<a name="lambda-managed-instances-nodejs-next-steps"></a>
+ Revise el [tiempo de ejecución de Java para instancias administradas de Lambda](lambda-managed-instances-java-runtime.md).
+ Revise el [tiempo de ejecución de Python para instancias administradas de Lambda](lambda-managed-instances-python-runtime.md).
+ Revise el [tiempo de ejecución de .NET para instancias administradas de Lambda](lambda-managed-instances-dotnet-runtime.md).
+ Obtenga información sobre el [escalado de instancias administradas de Lambda](lambda-managed-instances-scaling.md).

# Tiempo de ejecución de Python para instancias administradas de Lambda
<a name="lambda-managed-instances-python-runtime"></a>

El tiempo de ejecución de Lambda utiliza varios procesos de Python para gestionar las solicitudes simultáneas. Cada solicitud simultánea se ejecuta en un proceso independiente con su propio espacio de memoria e inicialización. Cada proceso gestiona una solicitud a la vez, de forma sincrónica. Los procesos no comparten memoria directamente, por lo que las variables globales, las cachés a nivel de módulo y los objetos individuales están aislados entre las solicitudes simultáneas.

## Configuración de concurrencia
<a name="lambda-managed-instances-python-concurrency-config"></a>

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 Python, el valor predeterminado es de 16 solicitudes simultáneas por vCPU, o puede configurar su propio valor. Este valor también determina el número de procesos utilizados por el tiempo de ejecución de Python. 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.

**importante**  
El uso de la concurrencia basada en procesos significa que cada proceso de trabajo en tiempo de ejecución realiza su propia inicialización. El uso total de la memoria es igual a la memoria por proceso multiplicada por el número de procesos simultáneos. Si carga bibliotecas o conjuntos de datos de gran tamaño y tiene una concurrencia elevada, tendrá un gran consumo de memoria. Según su carga de trabajo, es posible que necesite ajustar la proporción de CPU con respecto a la memoria o utilizar una configuración de concurrencia más baja para evitar sobrepasar la memoria disponible. Puede utilizar la métrica de `MemoryUtilization` de CloudWatch para hacer un seguimiento del consumo de memoria.

## Creación de funciones para la concurrencia múltiple
<a name="lambda-managed-instances-python-building"></a>

Debido al modelo de concurrencia múltiple basado en procesos, las funciones de las instancias administradas de Lambda que utilizan tiempos de ejecución de Python no acceden a los recursos en memoria de forma simultánea desde varias invocaciones. No es necesario aplicar prácticas de codificación para garantizar la concurrencia en memoria.

## Directorio /tmp compartido
<a name="lambda-managed-instances-python-shared-tmp"></a>

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 otro proceso sobrescribe el archivo. Para solucionar este problema, implemente el bloqueo de archivos para los archivos compartidos o utilice nombres de archivo únicos por proceso o por solicitud para evitar conflictos. Recuerde limpiar los archivos innecesarios para no agotar el espacio disponible.

## Registro
<a name="lambda-managed-instances-python-logging"></a>

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](monitoring-logs.md#monitoring-cloudwatchlogs-advanced). Este formato incluye el `requestId`, lo que permite correlacionar las entradas de registro con una sola solicitud. Cuando utiliza el módulo de `logging` de la biblioteca estándar de Python en Lambda, 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 Python](https://docs.aws.amazon.com/lambda/latest/dg/python-logging.html#python-logging-advanced).

## El contexto de la solicitud
<a name="lambda-managed-instances-python-request-context"></a>

Utilice `context.aws_request_id` para acceder al identificador de solicitud de la solicitud actual.

Con los tiempos de ejecución de Python, puede usar la variable de entorno `_X_AMZN_TRACE_ID` para acceder al identificador de seguimiento de X-Ray con instancias administradas de Lambda. El identificador de seguimiento de X-Ray se propaga automáticamente cuando se utiliza AWS SDK.

Utilice `context.get_remaining_time_in_millis()` para detectar tiempos de espera. Para obtener más información, consulte [Gestión de errores y recuperación](lambda-managed-instances-execution-environment.md#lambda-managed-instances-error-handling).

## Inicialización y apagado
<a name="lambda-managed-instances-python-init-shutdown"></a>

La inicialización de la función se produce una vez por proceso. Es posible que vea entradas de registro repetidas si su función emite registros durante la inicialización.

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 [Comprender el ciclo de vida del entorno de ejecución de Lambda](lambda-runtime-environment.md).

## Versiones de dependencias
<a name="lambda-managed-instances-python-dependencies"></a>

Las instancias administradas de Lambda requieren las siguientes versiones de paquete como mínimo:
+ Powertools para AWS Lambda (Python): versión 3.23.0 o posterior

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

Powertools para AWS Lambda (Python) es compatible con las instancias administradas de Lambda y proporciona utilidades para el registro, el seguimiento, las métricas y mucho más. Para obtener más información, consulte [Powertools para AWS Lambda (Python)](https://github.com/aws-powertools/powertools-lambda-python).

## Siguientes pasos
<a name="lambda-managed-instances-python-next-steps"></a>
+ Revise el [tiempo de ejecución de Java para instancias administradas de Lambda](lambda-managed-instances-java-runtime.md).
+ Revise el [tiempo de ejecución de Node.js para instancias administradas de Lambda](lambda-managed-instances-nodejs-runtime.md).
+ Revise el [tiempo de ejecución de .NET para instancias administradas de Lambda](lambda-managed-instances-dotnet-runtime.md).
+ Obtenga información sobre el [escalado de instancias administradas de Lambda](lambda-managed-instances-scaling.md).

# Tiempo de ejecución de .NET para instancias administradas de Lambda
<a name="lambda-managed-instances-dotnet-runtime"></a>

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
<a name="lambda-managed-instances-dotnet-concurrency-config"></a>

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
<a name="lambda-managed-instances-dotnet-building"></a>

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
<a name="lambda-managed-instances-dotnet-shared-tmp"></a>

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
<a name="lambda-managed-instances-dotnet-logging"></a>

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](monitoring-logs.md#monitoring-cloudwatchlogs-advanced). 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 información adicional, consulte [Uso de los controles de registro avanzados de Lambda con .NET](csharp-logging.md#csharp-logging-advanced).

## El contexto de la solicitud
<a name="lambda-managed-instances-dotnet-request-context"></a>

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.

Utilice `ILambdaContext.RemainingTime` para detectar tiempos de espera. Para obtener más información, consulte [Gestión de errores y recuperación](lambda-managed-instances-execution-environment.md#lambda-managed-instances-error-handling).

## Inicialización y apagado
<a name="lambda-managed-instances-dotnet-init-shutdown"></a>

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 [Comprender el ciclo de vida del entorno de ejecución de Lambda](lambda-runtime-environment.md).

## Versiones de dependencias
<a name="lambda-managed-instances-dotnet-dependencies"></a>

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)
<a name="lambda-managed-instances-dotnet-powertools"></a>

[Powertools para AWS Lambda (.NET)](https://docs.aws.amazon.com/powertools/dotnet/) y [AWS Distro para OpenTelemetry: la instrumentación para DotNet](https://github.com/aws-observability/aws-otel-dotnet-instrumentation) actualmente no admite instancias administradas de Lambda.

## Siguientes pasos
<a name="lambda-managed-instances-dotnet-next-steps"></a>
+ Revise el [tiempo de ejecución de Java para instancias administradas de Lambda](lambda-managed-instances-java-runtime.md).
+ Revise el [tiempo de ejecución de Node.js para instancias administradas de Lambda](lambda-managed-instances-nodejs-runtime.md).
+ Revise el [tiempo de ejecución de Python para instancias administradas de Lambda](lambda-managed-instances-python-runtime.md).
+ Obtenga información sobre el [escalado de instancias administradas de Lambda](lambda-managed-instances-scaling.md).

# Compatibilidad de Rust con instancias administradas de Lambda
<a name="lambda-managed-instances-rust"></a>

## Configuración de concurrencia
<a name="lambda-managed-instances-rust-concurrency-config"></a>

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
<a name="lambda-managed-instances-rust-building"></a>

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 [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). 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 [https://doc.rust-lang.org/std/sync/struct.Arc.html](https://doc.rust-lang.org/std/sync/struct.Arc.html) 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
<a name="lambda-managed-instances-rust-example-sdk"></a>

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
<a name="lambda-managed-instances-rust-example-db"></a>

Cuando el controlador necesita acceder a estado compartido, como un cliente y una configuración, encapsúlelo en [https://doc.rust-lang.org/std/sync/struct.Arc.html](https://doc.rust-lang.org/std/sync/struct.Arc.html) 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
<a name="lambda-managed-instances-rust-tmp"></a>

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
<a name="lambda-managed-instances-rust-logging"></a>

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](monitoring-logs.md#monitoring-cloudwatchlogs-advanced) 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](rust-logging.md#rust-logging-tracing).

## Contexto de la solicitud
<a name="lambda-managed-instances-rust-context"></a>

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
<a name="lambda-managed-instances-rust-lifecycle"></a>

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, [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). 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](lambda-runtime-environment.md).

## Versiones de dependencias
<a name="lambda-managed-instances-rust-dependencies"></a>

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.