Lambda 관리형 인스턴스용 Node.js 런타임 - AWS Lambda

Lambda 관리형 인스턴스용 Node.js 런타임

Node.js 런타임의 경우 Lambda 관리형 인스턴스는 async/await 기반 실행과 함께 작업자 스레드를 사용하여 동시 요청을 처리합니다. 함수 초기화는 작업자 스레드당 한 번 발생합니다. 동시 간접 호출은 2가지 차원에서 처리됩니다. 작업자 스레드는 vCPU 간에 병렬 처리를 제공하고, 비동기 실행은 각 스레드 내에서 동시성을 제공합니다. 동일한 작업자 스레드에서 처리하는 각 동시 요청은 동일한 핸들러 객체와 전역 상태를 공유하기에 여러 동시 요청에서의 안전한 처리가 필요합니다.

최대 동시성

Lambda가 각 실행 환경에 보내는 최대 동시 요청 수는 함수 구성의 PerExecutionEnvironmentMaxConcurrency 설정으로 제어됩니다. 이 설정은 선택 사항이며, 기본값은 런타임에 따라 달라집니다. Node.js 런타임의 경우 기본값은 vCPU당 64개 동시 요청으로, 또는 자체 값을 구성할 수 있습니다. Lambda는 각 실행 환경의 용량에 따라 구성된 최대 수까지 동시 요청 수를 자동으로 조정하여 이러한 요청을 수용합니다.

Node.js의 경우 각 실행 환경에서 처리할 수 있는 동시 요청 수는 작업자 스레드 수와 동시 요청을 비동기식으로 처리하는 각 작업자 스레드의 용량에 따라 결정됩니다. 기본 작업자 스레드 수는 사용 가능한 vCPU 수에 따라 결정됩니다. 또는 AWS_LAMBDA_NODEJS_WORKER_COUNT 환경 변수를 설정하여 작업자 스레드 수를 구성할 수 있습니다. 비동기 함수 핸들러를 사용하면 작업자 스레드당 여러 요청을 처리할 수 있어 사용이 권장됩니다. 함수 핸들러가 동기식인 경우 각 작업자 스레드는 한 번에 하나의 요청만 처리할 수 있습니다.

다중 동시성 함수 빌드

비동기 함수 핸들러를 사용하면 각 런타임 작업자가 여러 개의 요청을 동시에 처리합니다. 전역 객체가 여러 동시 요청에서 공유됩니다. 변경 가능한 객체의 경우 전역 상태를 사용하지 않거나 AsyncLocalStorage를 사용합니다.

AWS SDK 클라이언트는 비동기식으로 안전하기에 별도의 처리가 필요하지 않습니다.

예제: 전역 상태

다음 코드는 함수 핸들러 내에서 변형되는 전역 객체를 사용합니다. 비동기식에서 사용하기에 안전하지 않습니다.

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

함수 핸들러 내에서 state 객체를 초기화하면 전역 상태가 공유되지 않습니다.

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

예제: 데이터베이스 연결

다음 코드는 여러 간접 호출 간에 공유되는 클라이언트 객체를 사용합니다. 사용되는 연결 라이브러리에 따라 동시성이 안전하지 않을 수 있습니다.

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

동시성에 있어 안전한 방식은 연결 풀을 사용하는 것입니다. 풀은 각 동시 데이터베이스 쿼리에 별도의 연결을 사용합니다.

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 콜백 기반 핸들러

Node.js 22를 사용하는 경우 Lambda 관리형 인스턴스에서 콜백 기반 함수 핸들러를 사용할 수 없습니다. 콜백 기반 핸들러는 Lambda(기본값) 함수에서만 지원됩니다. Node.js 24 이상 런타임의 경우 Lambda(기본값) 및 Lambda 관리형 인스턴스 모두에서 콜백 기반 함수 핸들러가 더 이상 사용되지 않습니다.

대신 Lambda 관리형 인스턴스를 사용할 때는 async 함수 핸들러를 사용하세요. 자세한 내용은 Node.js에서 Lambda 함수 핸들러 정의를 참조하세요.

공유 /tmp 디렉터리

/tmp 디렉터리는 실행 환경의 모든 동시 요청에서 공유됩니다. 동일한 파일에 대한 동시 쓰기로 인해 다른 프로세스가 파일을 덮어쓰는 등 데이터가 손상될 수 있습니다. 이를 해결하려면 공유 파일에 대한 파일 잠금을 구현하거나 요청당 고유한 파일 이름을 사용하여 충돌을 방지합니다. 사용 가능한 공간이 소진되지 않도록 불필요한 파일을 정리해야 합니다.

로깅

다중 동시 시스템에서는 로그 인터리브(로그에서 서로 다른 요청의 로그 항목이 인터리브됨)가 정상적인 동작입니다. Lambda 관리형 인스턴스를 사용하는 함수는 항상 고급 로깅 제어가 도입된 구조화된 JSON 로그 형식을 사용합니다. 이 형식에는 requestId가 포함되어 로그 항목을 단일 요청과 연관시킬 수 있습니다. console 로거를 사용하면 requestId가 각 로그 항목에 자동으로 포함됩니다. 자세한 내용은 Node.js에서 Lambda 고급 로깅 제어 사용을 참조하세요.

Winston과 같이 많이 사용되는 타사 로깅 라이브러리에는 일반적으로 로그 출력에 콘솔 사용 지원이 포함되어 있습니다.

요청 컨텍스트

context.awsRequestId를 사용하면 현재 요청의 요청 ID에 대해 비동기식 안전 액세스가 가능합니다.

context.xRayTraceId를 사용하여 X-Ray 트레이스 ID에 액세스합니다. 이렇게 하면 현재 요청의 트레이스 ID에 대한 동시성 안전 액세스 권한이 제공됩니다. Lambda는 Lambda 관리형 인스턴스에서 _X_AMZN_TRACE_ID 환경 변수를 지원하지 않습니다. AWS SDK를 사용할 때 X-Ray 트레이스 ID가 자동으로 전파됩니다.

초기화 및 종료

함수 초기화는 작업자 스레드당 한 번 발생합니다. 함수가 초기화 도중 로그를 내보내는 경우 반복 로그 항목이 표시될 수 있습니다.

확장이 포함된 Lambda 함수의 경우 실행 환경은 종료 중에 SIGTERM 신호를 내보냅니다. 이 신호는 확장에서 버퍼 비우기와 같은 정리 태스크를 트리거하는 데 사용됩니다. 확장이 포함된 Lambda(기본값) 함수는 process.on()을 사용하여 SIGTERM 신호를 구독할 수도 있습니다. process.on()은 작업자 스레드에서 사용할 수 없으므로 Lambda 관리형 인스턴스를 사용하는 함수에서는 지원되지 않습니다. 실행 환경 수명 주기에 대한 자세한 내용은 Lambda 실행 환경 수명 주기 이해를 참조하세요.

종속성 버전

Lambda 관리형 인스턴스에는 다음과 같은 최소 패키지 버전이 필요합니다.

  • AWS SDK for JavaScript v3: 버전 3.933.0 이상

  • AWS X-Ray SDK for Node.js: 버전 3.12.0 이상

  • AWS Distro for OpenTelemetry - Instrumentation for JavaScript: 버전 0.8.0 이상

  • Powertools for AWS Lambda(TypeScript): 버전 2.29.0 이상

Powertools for AWS Lambda(TypeScript)

Powertools for AWS Lambda(TypeScript)는 Lambda 관리형 인스턴스와 호환되고 로깅, 추적, 지표 등을 위한 유틸리티를 제공합니다. 자세한 내용은 Powertools for AWS Lambda(TypeScript)를 참조하세요.

다음 단계