View a markdown version of this page

Node.js Laufzeit für Lambda Managed Instances - AWS Lambda

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Node.js Laufzeit für Lambda Managed Instances

Für Node.js Laufzeiten verwendet Lambda Managed Instances Worker-Threads mitasync/await-basierter Ausführung, um gleichzeitige Anfragen zu verarbeiten. Die Funktionsinitialisierung erfolgt einmal pro Worker-Thread. Gleichzeitige Aufrufe werden in zwei Dimensionen verarbeitet: Worker-Threads sorgen für Parallelität zwischen den vCPUs, und die asynchrone Ausführung sorgt für Parallelität innerhalb jedes Threads. Jede gleichzeitige Anforderung, die von demselben Worker-Thread bearbeitet wird, hat dasselbe Handler-Objekt und denselben globalen Status, sodass eine sichere Verarbeitung bei mehreren gleichzeitigen Anforderungen erforderlich ist.

Maximale Parallelität

Die maximale Anzahl gleichzeitiger Anfragen, die Lambda an jede Ausführungsumgebung sendet, wird durch die PerExecutionEnvironmentMaxConcurrency Einstellung in der Funktionskonfiguration gesteuert. Dies ist eine optionale Einstellung, und der Standardwert variiert je nach Laufzeit. Für Node.js Laufzeiten ist die Standardeinstellung 64 gleichzeitige Anforderungen pro vCPU, oder Sie können Ihren eigenen Wert konfigurieren. Lambda passt die Anzahl der gleichzeitigen Anforderungen automatisch bis zum konfigurierten Maximum an, basierend auf der Kapazität der einzelnen Ausführungsumgebungen, diese Anforderungen zu verarbeiten.

Denn die Anzahl der gleichzeitigen Anforderungen Node.js, die jede Ausführungsumgebung verarbeiten kann, wird durch die Anzahl der Worker-Threads und die Fähigkeit jedes Worker-Threads bestimmt, gleichzeitige Anforderungen asynchron zu verarbeiten. Die Standardanzahl der Worker-Threads wird durch die Anzahl der verfügbaren vCPUs bestimmt, oder Sie können die Anzahl der Worker-Threads konfigurieren, indem Sie die Umgebungsvariable festlegen. AWS_LAMBDA_NODEJS_WORKER_COUNT Wir empfehlen, asynchrone Funktionshandler zu verwenden, da auf diese Weise mehrere Anfragen pro Worker-Thread verarbeitet werden können. Wenn Ihr Funktionshandler synchron ist, kann jeder Worker-Thread jeweils nur eine einzige Anforderung verarbeiten.

Erstellung von Funktionen für Mehrfachparallelität

Mit einem asynchronen Funktionshandler verarbeitet jeder Runtime-Worker mehrere Anfragen gleichzeitig. Globale Objekte werden von mehreren gleichzeitigen Anforderungen gemeinsam genutzt. Vermeiden Sie bei veränderlichen Objekten die Verwendung von Global State oder use. AsyncLocalStorage

AWS SDK-Clients sind asynchron-sicher und erfordern keine besondere Behandlung.

Beispiel: Globaler Staat

Der folgende Code verwendet ein globales Objekt, das im Funktionshandler mutiert ist. Dies ist nicht asynchron-sicher.

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

Durch die Initialisierung des state Objekts im Funktionshandler wird ein gemeinsamer globaler Status vermieden.

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

Beispiel: Datenbankverbindungen

Der folgende Code verwendet ein gemeinsames Client-Objekt, das von mehreren Aufrufen gemeinsam genutzt wird. Je nach verwendeter Verbindungsbibliothek ist dies möglicherweise nicht sicher für Parallelität.

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

Ein parallelitätssicherer Ansatz besteht darin, einen Verbindungspool zu verwenden. Der Pool verwendet für jede gleichzeitige Datenbankabfrage eine separate Verbindung.

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 Callback-basierte Handler

Wenn Sie Node.js 22 verwenden, können Sie keinen Callback-basierten Funktionshandler mit Lambda Managed Instances verwenden. Callback-based Handler werden nur für Lambda-Funktionen (Standard) unterstützt. Für Laufzeiten ab Node.js 24 Jahren sind Callback-basierte Funktionshandler sowohl für Lambda (Standard) als auch für Lambda Managed Instances veraltet.

Verwenden Sie stattdessen einen Funktionshandler, wenn Sie Lambda Managed Instances async verwenden. Weitere Informationen finden Sie unter Definieren Sie den Lambda-Funktionshandler in. Node.js

Gemeinsames /tmp-Verzeichnis

Das /tmp Verzeichnis wird von allen gleichzeitigen Anforderungen in der Ausführungsumgebung gemeinsam genutzt. Gleichzeitige Schreibvorgänge in dieselbe Datei können zu Datenbeschädigungen führen, z. B. wenn ein anderer Prozess die Datei überschreibt. Um dieses Problem zu beheben, implementieren Sie entweder Dateisperren für gemeinsam genutzte Dateien oder verwenden Sie pro Anfrage eindeutige Dateinamen, um Konflikte zu vermeiden. Denken Sie daran, nicht benötigte Dateien zu bereinigen, um zu vermeiden, dass der verfügbare Speicherplatz ausgeschöpft wird.

Protokollierung

Das Verschachteln von Protokollen (Protokolleinträge aus verschiedenen Anfragen werden in Protokollen verschachtelt) ist bei Systemen mit mehreren gleichzeitigen Vorgängen normal. Funktionen, die Lambda Managed Instances verwenden, verwenden immer das strukturierte JSON-Protokollformat, das mit erweiterten Protokollierungssteuerungen eingeführt wurde. Konfigurieren erweiterter Protokollierungsoptionen für Lambda-Funktionen Dieses Format beinhaltet dasrequestId, sodass Logeinträge einer einzelnen Anfrage zugeordnet werden können. Wenn Sie den console Logger verwenden, requestId ist der automatisch in jedem Protokolleintrag enthalten. Weitere Informationen finden Sie unterVerwenden Sie die erweiterten Logging-Steuerelemente von Lambda mit Node.js.

Beliebte Protokollierungsbibliotheken von Drittanbietern, wie Winston, unterstützen in der Regel die Verwendung der Konsole für die Protokollausgabe.

Kontext anfordern

Using context.awsRequestId bietet asynchronen Zugriff auf die Anforderungs-ID für die aktuelle Anfrage.

Wird für context.xRayTraceId den Zugriff auf die X-Ray Trace-ID verwendet. Dies ermöglicht den parallelen Zugriff auf die Trace-ID für die aktuelle Anfrage. Lambda unterstützt die _X_AMZN_TRACE_ID Umgebungsvariable mit Lambda Managed Instances nicht. Die X-Ray Trace-ID wird automatisch weitergegeben, wenn das SDK verwendet wird. AWS

Wird verwendetcontext.getRemainingTimeInMillis(), um Timeouts zu erkennen. Weitere Informationen finden Sie unter Fehlerbehandlung und Wiederherstellung.

Beispiel: Behandlung von Timeouts

Prüfen Sie die verbleibende Zeit vor jeder Arbeitseinheit und beenden Sie die Verarbeitung, bevor der Timeout ausgelöst wird. Konfigurieren Sie die Konfiguration auf der BUFFER_MS Grundlage der erwarteten Dauer Ihres nächsten Arbeitsabschnitts.

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

Beispiel: Weitergabe von Terminen an Downstream-Aufrufe

Wenn Sie nachgelagerte Dienste aufrufen, geben Sie die verbleibende Zeit als Timeout an, um zu vermeiden, dass Netzwerkaufrufe, die Ihren Aufruf überdauern würden, hängen bleiben:

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

Initialisierung und Herunterfahren

Die Funktionsinitialisierung erfolgt einmal pro Worker-Thread. Möglicherweise werden wiederholte Protokolleinträge angezeigt, wenn Ihre Funktion während der Initialisierung Protokolle ausgibt.

Bei Lambda-Funktionen mit Erweiterungen gibt die Ausführungsumgebung beim Herunterfahren ein SIGTERM-Signal aus. Dieses Signal wird von Erweiterungen verwendet, um Bereinigungsaufgaben wie das Leeren von Puffern auszulösen. Lambda-Funktionen (Standard) mit Erweiterungen können das SIGTERM-Signal auch mithilfe von abonnieren. process.on() Dies wird für Funktionen, die Lambda Managed Instances verwenden, nicht unterstützt, da es process.on() nicht mit Worker-Threads verwendet werden kann. Weitere Informationen zum Lebenszyklus der Ausführungsumgebung finden Sie unter Verständnis des Lebenszyklus der Lambda-Ausführungsumgebung.

Versionen, die abhängig sind

Für Lambda Managed Instances sind die folgenden Mindestpaketversionen erforderlich:

  • AWS SDK für JavaScript v3: Version 3.933.0 oder höher

  • AWS X-Ray SDK für Node.js: Version 3.12.0 oder höher

  • AWS Distro für OpenTelemetry - Instrumentierung für JavaScript: Version 0.8.0 oder höher

  • Powertools for AWS Lambda (TypeScript): Version 2.29.0 oder höher

Elektrowerkzeuge für AWS Lambda () TypeScript

Powertools for AWS Lambda (TypeScript) ist mit Lambda Managed Instances kompatibel und bietet Hilfsprogramme für Logging, Tracing, Metriken und mehr. Weitere Informationen finden Sie unter Powertools for Lambda (). AWS TypeScript

Nächste Schritte