Runtime de Node.js para instâncias gerenciadas do Lambda
Para runtimes de Node.js, as instâncias gerenciadas do Lambda usam threads de operador com execução async/await para lidar com solicitações simultâneas. A inicialização da função ocorre uma vez por thread de operador. As invocações simultâneas são tratadas em duas dimensões: os threads de operador fornecem paralelismo entre vCPUs e a execução assíncrona fornece simultaneidade em cada thread. Cada solicitação simultânea tratada pelo mesmo thread de operador compartilha o mesmo objeto manipulador e estado global, exigindo tratamento seguro em várias solicitações simultâneas.
Simultaneidade máxima
O número máximo de solicitações simultâneas que o Lambda envia para cada ambiente de execução é controlado pela definição PerExecutionEnvironmentMaxConcurrency da configuração da função. Essa é uma definição opcional e o valor padrão varia de acordo com o runtime. Para os runtimes de Node.js, o padrão é 64 solicitações simultâneas por vCPU, ou é possível configurar seu próprio valor. O Lambda ajusta automaticamente o número de solicitações simultâneas até o máximo configurado com base na capacidade de cada ambiente de execução de absorver essas solicitações.
Para o Node.js, o número de solicitações simultâneas que cada ambiente de execução pode processar é determinado pelo número de threads de operador e pela capacidade de cada thread de operador de processar solicitações simultâneas de forma assíncrona. O número padrão de threads de operador é determinado pelo número de vCPUs disponíveis, ou é possível configurar o número de threads de operador definindo a variável de ambiente AWS_LAMBDA_NODEJS_WORKER_COUNT. Recomendamos o uso de manipuladores de funções assíncronos, pois isso permite processar várias solicitações por thread de operador. Se seu manipulador de funções for síncrono, cada thread de operador só poderá processar uma única solicitação por vez.
Funções de construção para multissimultaneidade
Com um manipulador de funções assíncrono, cada operador de runtime processa várias solicitações simultaneamente. Objetos globais serão compartilhados por várias solicitações simultâneas. Para objetos mutáveis, evite usar o estado global ou use AsyncLocalStorage.
Os clientes de SDK da AWS são seguros para assincronia e não exigem tratamento especial.
Exemplo: estado global
O código a seguir usa um objeto global que sofre mutação dentro do manipulador de funções. Isso não é seguro para uso assíncrono.
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 }; };
Inicializar o objeto state dentro do manipulador de funções evita o estado global compartilhado.
export const handler = async (event, context) => { let state = { currentUser: event.userId, requestData: event.data }; await processData(state.requestData); return { user: state.currentUser }; };
Exemplo: conexões de banco de dados
O código a seguir usa um objeto cliente compartilhado que é compartilhado entre várias invocações. Dependendo da biblioteca de conexão usada, isso pode não ser seguro para simultaneidade.
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]) }; };
Uma abordagem segura para simultaneidade é usar um grupo de conexões. O grupo usa uma conexão separada para cada consulta simultânea ao banco de dados.
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]) }; };
Manipuladores baseados em retorno de chamada do Node.js 22
Ao usar o Node.js 22, não é possível usar um manipulador de funções baseado em retorno de chamada com instâncias gerenciadas do Lambda. Há suporte para manipuladores baseados em retorno de chamada apenas com funções do Lambda (padrão). Para runtimes do Node.js 24 e posteriores, os manipuladores de funções baseados em retorno de chamada estão obsoletos tanto para o Lambda (padrão) quanto para instâncias gerenciadas do Lambda.
Em vez disso, use um manipulador de funções async ao usar instâncias gerenciadas do Lambda. Para obter mais informações, consulte Definição do manipulador de função do Lambda em Node.js.
Diretório /tmp compartilhado
O diretório /tmp é compartilhado entre todas as solicitações simultâneas no ambiente de execução. Gravações simultâneas no mesmo arquivo podem causar corrupção de dados, por exemplo, se outro processo sobrescrever o arquivo. Para resolver isso, implemente o bloqueio de arquivos para arquivos compartilhados ou use nomes de arquivo exclusivos por solicitação para evitar conflitos. Lembre-se de limpar arquivos desnecessários para evitar o esgotamento do espaço disponível.
Registro em log
A intercalação de logs (entradas de logs de solicitações diferentes sendo intercaladas em logs) é normal em sistemas multissimultâneos. As funções que usam instâncias gerenciadas do Lambda sempre usam o formato de log de JSON estruturado introduzido com controles de registro em log avançados. Esse formato inclui o requestId, permitindo que as entradas de log sejam correlacionadas a uma única solicitação. Quando você usa o logger console, o requestId é incluído automaticamente em cada entrada de log. Para obter mais informações, consulte Uso de controles avançados de registro em log do Lambda com Node.js.
Bibliotecas de registro em log populares de terceiros, como a Winston
Contexto da solicitação
O uso de context.awsRequestId proporciona acesso com segurança de assincronia para acessar o ID da solicitação atual.
Use context.xRayTraceId para acessar o ID de rastreamento do X-Ray. Isso fornece acesso com segurança de simultaneidade ao ID de rastreamento da solicitação atual. O Lambda não oferece suporte à variável de ambiente _X_AMZN_TRACE_ID com instâncias gerenciadas do Lambda. O ID de rastreamento do X-Ray é propagado automaticamente ao usar o AWS SDK.
Inicialização e desligamento
A inicialização da função ocorre uma vez por thread de operador. É possível visualizar ver entradas de log repetidas se sua função emitir logs durante a inicialização.
Para as funções do Lambda com extensões, o ambiente de execução emite um sinal SIGTERM durante o desligamento. Esse sinal é usado pelas extensões para acionar tarefas de limpeza, como descarregar buffers. Funções do Lambda (padrão) com extensões também podem assinar o sinal SIGTERM usando.process.on(). Não há suporte para isso em funções que usam instâncias gerenciadas do Lambda, pois process.on() não pode ser usado com threads de operador. Para saber mais sobre o ciclo de vida do ambiente de execução, consulte Noções básicas sobre o ciclo de vida do ambiente de execução do Lambda.
Versões de dependências
As instâncias gerenciadas do Lambda exigem as versões mínimas de pacotes a seguir:
-
AWS SDK para JavaScript v3: versão 3.933.0 ou posterior
-
AWS X-Ray SDK para Node.js: versão 3.12.0 ou posterior
-
AWS Distro para OpenTelemetry - Instrumentação para JavaScript: versão 0.8.0 ou posterior
-
Powertools para AWS Lambda (TypeScript): versão 2.29.0 ou posterior
Powertools para AWS Lambda (TypeScript)
O Powertools para AWS Lambda (TypeScript) é compatível com as instâncias gerenciadas do Lambda e fornece utilitários para registro em log, rastreamento, métricas e muito mais. Para obter mais informações, consulte Powertools para AWS Lambda (TypeScript)