Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.
Node.js environnement d'exécution pour les instances gérées Lambda
Pour les Node.js environnements d'exécution, les instances gérées Lambda utilisent des threads de travail async avec une exécution basée surawait/pour gérer les demandes simultanées. L'initialisation de la fonction a lieu une fois par thread de travail. Les appels simultanés sont gérés selon deux dimensions : les threads de travail assurent le parallélisme entre les vCPU, et l'exécution asynchrone assure la simultanéité au sein de chaque thread. Chaque demande simultanée traitée par le même thread de travail partage le même objet de gestionnaire et le même état global, ce qui nécessite un traitement sécurisé dans le cadre de plusieurs demandes simultanées.
Simultanéité maximum
Le nombre maximum de demandes simultanées que Lambda envoie à chaque environnement d'exécution est contrôlé par le PerExecutionEnvironmentMaxConcurrency paramètre de configuration de la fonction. Il s'agit d'un paramètre facultatif, et la valeur par défaut varie en fonction du temps d'exécution. Pour les Node.js environnements d'exécution, la valeur par défaut est de 64 requêtes simultanées par vCPU, ou vous pouvez configurer votre propre valeur. Lambda ajuste automatiquement le nombre de demandes simultanées jusqu'au maximum configuré en fonction de la capacité de chaque environnement d'exécution à absorber ces demandes.
En Node.js effet, le nombre de demandes simultanées que chaque environnement d'exécution peut traiter est déterminé par le nombre de threads de travail et par la capacité de chaque thread de travail à traiter les demandes simultanées de manière asynchrone. Le nombre de threads de travail par défaut est déterminé par le nombre de vCPU disponibles. Vous pouvez également configurer le nombre de threads de travail en définissant la variable d'AWS_LAMBDA_NODEJS_WORKER_COUNTenvironnement. Nous recommandons d'utiliser des gestionnaires de fonctions asynchrones, car cela permet de traiter plusieurs demandes par thread de travail. Si votre gestionnaire de fonctions est synchrone, chaque thread de travail ne peut traiter qu'une seule demande à la fois.
Création de fonctions pour la multisimultanéité
Avec un gestionnaire de fonctions asynchrones, chaque utilisateur d'exécution traite plusieurs demandes simultanément. Les objets globaux seront partagés entre plusieurs demandes simultanées. Pour les objets mutables, évitez d'utiliser un état ou un usage AsyncLocalStorage global.
AWS Les clients du SDK sont sécurisés en mode asynchrone et ne nécessitent aucune manipulation particulière.
Exemple : État global
Le code suivant utilise un objet global qui est muté dans le gestionnaire de fonctions. Ce n'est pas sécurisé en mode asynchrone.
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 }; };
L'initialisation de l'stateobjet dans le gestionnaire de fonctions permet d'éviter un état global partagé.
export const handler = async (event, context) => { let state = { currentUser: event.userId, requestData: event.data }; await processData(state.requestData); return { user: state.currentUser }; };
Exemple : connexions à la base de données
Le code suivant utilise un objet client partagé qui est partagé entre plusieurs invocations. Selon la bibliothèque de connexions utilisée, il se peut que cela ne soit pas sûr en matière de simultanéité.
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]) }; };
Une approche sûre en matière de simultanéité consiste à utiliser un pool de connexions. Le pool utilise une connexion distincte pour chaque requête de base de données simultanée.
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]) }; };
Node.js 22 gestionnaires basés sur des rappels
Lorsque vous utilisez Node.js 22, vous ne pouvez pas utiliser de gestionnaire de fonctions basé sur le rappel avec les instances gérées Lambda. Callback-based les gestionnaires ne sont pris en charge que pour les fonctions Lambda (par défaut). Pour les Node.js environnements d'exécution 24 et suivants, les gestionnaires de fonctions basés sur le rappel sont déconseillés pour les instances Lambda (par défaut) et Lambda Managed Instances.
Utilisez plutôt un gestionnaire de async fonctions lorsque vous utilisez des instances gérées Lambda. Pour plus d'informations, voir Définir le gestionnaire de fonctions Lambda dans. Node.js
Répertoire /tmp partagé
Le /tmp répertoire est partagé entre toutes les demandes simultanées dans l'environnement d'exécution. Les écritures simultanées dans le même fichier peuvent entraîner une corruption des données, par exemple si un autre processus remplace le fichier. Pour résoudre ce problème, implémentez le verrouillage des fichiers partagés ou utilisez des noms de fichiers uniques par demande afin d'éviter les conflits. N'oubliez pas de nettoyer les fichiers inutiles pour ne pas épuiser l'espace disponible.
Logging
L'entrelacement des journaux (les entrées des journaux provenant de différentes demandes sont entrelacées dans des journaux) est normal dans les systèmes multiconcurrents. Les fonctions utilisant des instances gérées Lambda utilisent toujours le format de journal JSON structuré introduit avec les contrôles de journalisation avancés. Ce format inclut lerequestId, ce qui permet de corréler les entrées du journal à une seule demande. Lorsque vous utilisez l'consoleenregistreur, il requestId est automatiquement inclus dans chaque entrée du journal. Pour de plus amples informations, voirUtilisation des contrôles de journalisation avancés de Lambda avec Node.js.
Les bibliothèques de journalisation tierces les plus populaires, telles que Winston
Contexte de la requête
L'utilisation context.awsRequestId fournit un accès asynchrone à l'ID de demande pour la demande en cours.
context.xRayTraceIdÀ utiliser pour accéder à l'ID de X-Ray trace. Cela fournit un accès simultané à l'ID de trace pour la demande en cours. Lambda ne prend pas en charge la variable d'_X_AMZN_TRACE_IDenvironnement avec les instances gérées par Lambda. L'ID de X-Ray trace est propagé automatiquement lors de l'utilisation du AWS SDK.
context.getRemainingTimeInMillis()À utiliser pour détecter les délais d'expiration. Pour plus d’informations, consultez Gestion des erreurs et restauration.
Exemple : gestion des délais
Vérifiez le temps restant avant chaque unité de travail et arrêtez le traitement avant que le délai d'expiration ne se déclenche. Configurez en BUFFER_MS fonction de la durée prévue de votre prochaine tâche.
const BUFFER_MS = 2000; // Configure based on your next chunk of work exports.handler = async (event, context) => { for (const item of event.items) { if (context.getRemainingTimeInMillis() < BUFFER_MS) return { statusCode: 206, body: "Timeout approaching, stopping early" }; await processItem(item); } return { statusCode: 200, body: "Done" }; };
Exemple : propagation des délais aux appels en aval
Lorsque vous appelez des services en aval, répartissez le temps restant sous forme de délai d'expiration pour éviter de vous retrouver dans des appels réseau qui survivraient à votre invocation :
const { S3Client, GetObjectCommand } = require("@aws-sdk/client-s3"); const client = new S3Client({}); exports.handler = async (event, context) => { const timeout = Math.max(1000, context.getRemainingTimeInMillis() - 500); const response = await client.send( new GetObjectCommand({ Bucket: "my-bucket", Key: "my-key" }), { abortSignal: AbortSignal.timeout(timeout) } ); return { statusCode: 200, body: "Done" }; };
Initialisation et arrêt
L'initialisation de la fonction a lieu une fois par thread de travail. Des entrées de journal répétées peuvent s'afficher si votre fonction émet des journaux lors de l'initialisation.
Pour les fonctions Lambda avec extensions, l'environnement d'exécution émet un signal SIGTERM lors de l'arrêt. Ce signal est utilisé par les extensions pour déclencher des tâches de nettoyage, telles que le vidage des tampons. Les fonctions Lambda (par défaut) avec extensions peuvent également s'abonner au signal SIGTERM en utilisant. process.on() Ceci n'est pas pris en charge pour les fonctions utilisant des instances gérées Lambda car il process.on() ne peut pas être utilisé avec les threads de travail. Pour en savoir plus sur le cycle de vie de l'environnement d'exécution, veuillez consulter Comprendre le cycle de vie de l’environnement d’exécution Lambda.
Versions de dépendance
Les instances gérées Lambda nécessitent les versions de package minimales suivantes :
-
AWS SDK pour JavaScript v3 : version 3.933.0 ou ultérieure
-
AWS X-Ray SDK pour Node.js : version 3.12.0 ou ultérieure
-
AWS Distro pour OpenTelemetry - Instrumentation pour JavaScript : version 0.8.0 ou ultérieure
-
Powertools pour AWS Lambda TypeScript () : version 2.29.0 ou ultérieure
Outils électriques pour AWS Lambda () TypeScript
Powertools for AWS Lambda TypeScript () est compatible avec les instances gérées par Lambda et fournit des utilitaires pour la journalisation, le suivi, les métriques, etc. Pour plus d'informations, consultez Powertools for AWS Lambda TypeScript
Étapes suivantes
-
Passez en revue l'environnement d'exécution Java pour les instances gérées Lambda
-
Passez en revue le runtime Python pour les instances gérées Lambda
-
Passez en revue l'environnement d'exécution .NET pour les instances gérées Lambda
-
En savoir plus sur le dimensionnement des instances gérées Lambda