Lambda 관리형 인스턴스에 대한 Rust 지원 - AWS Lambda

Lambda 관리형 인스턴스에 대한 Rust 지원

동시성 구성

Lambda가 각 실행 환경에 보내는 최대 동시 요청 수는 함수 구성의 PerExecutionEnvironmentMaxConcurrency 설정으로 제어됩니다. 이 설정은 선택 사항이며, Rust의 기본값은 vCPU당 동시 요청 8개이고, 자체 값을 구성할 수 있습니다. 이 값은 런타임에서 생성된 Tokio 태스크 수를 결정하며 실행 환경의 수명 동안 변하지 않습니다. 각 작업자는 작업자당 멀티플렉싱 없이 한 번에 정확히 하나의 진행 중인 요청을 처리합니다. Lambda는 각 실행 환경의 용량에 따라 구성된 최대 수까지 동시 요청 수를 자동으로 조정하여 이러한 요청을 수용합니다.

다중 동시성 함수 빌드

Lambda 관리형 인스턴스를 사용할 때는 다른 다중 스레드 환경에서와 동일한 스레드 안전 관행을 적용해야 합니다. 핸들러 객체는 모든 작업자 스레드에서 공유되므로 변경 가능한 상태는 스레드 안전 상태여야 합니다. 여기에는 컬렉션, 데이터베이스 연결 및 요청 처리 도중 수정된 모든 정적 객체가 포함됩니다.

동시 요청 처리를 활성화하려면 Cargo.toml 파일에 concurrency-tokio 특성 플래그를 추가합니다.

[dependencies] lambda_runtime = { version = "1", features = ["concurrency-tokio"] }

lambda_runtime::run_concurrent(…) 진입점은 Tokio 런타임 내에서 직접적으로 호출되어야 하며, 일반적으로 기본 함수의 #[tokio::main] 속성에서 제공됩니다. 핸들러 종료에서는 Clone + Send를 구현해야 합니다. 그러면 프레임워크가 여러 비동기식 태스크에서 핸들러를 안전하게 공유할 수 있습니다. 이러한 경계가 충족되지 않으면 코드가 컴파일되지 않습니다.

간접 호출(데이터베이스 풀, 구성 구조) 간에 공유된 상태가 필요하면 Arc로 래핑하고 각 간접 호출에 Arc를 복제합니다.

모든 AWS SDK for Rust 클라이언트는 동시성에 안전하며 특별한 처리가 필요하지 않습니다.

예: AWS SDK 클라이언트

다음 예제에서는 S3 클라이언트를 사용하여 간접 호출마다 객체를 업로드합니다. 클라이언트는 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

예제: 데이터베이스 연결 풀

핸들러에서 클라이언트 및 구성과 같은 공유된 상태에 액세스해야 한다면 Arc로 래핑하고 각 간접 호출에 Arc를 복제합니다.

#[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

공유 /tmp 디렉터리

/tmp 디렉터리는 동일한 실행 환경의 모든 동시 간접 호출에서 공유됩니다. 간접 호출당 고유한 파일 이름을 사용하거나(예: 요청 ID 포함) 명시적 파일 잠금을 구현하여 데이터 손상을 방지합니다.

로깅

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

요청 컨텍스트

Context 객체는 각 핸들러 간접 호출에 직접 전달됩니다. event.context.request_id를 사용하여 현재 요청의 요청 ID에 액세스합니다.

event.context.xray_trace_id를 사용하여 X-Ray 트레이스 ID에 액세스합니다. Lambda는 Lambda 관리형 인스턴스에서 _X_AMZN_TRACE_ID 환경 변수를 지원하지 않습니다. AWS SDK for Rust를 사용할 때 X-Ray 트레이스 ID가 자동으로 전파됩니다.

event.context.deadline를 사용하여 제한 시간을 탐지합니다. 밀리초 단위의 간접 호출 기한이 있습니다.

초기화 및 종료

함수 초기화는 실행 환경당 한 번 발생합니다. 초기화 도중 생성된 객체는 요청 간에 공유됩니다.

확장이 포함된 Lambda 함수의 경우 실행 환경은 종료 중에 SIGTERM 신호를 내보냅니다. 이 신호는 확장에서 버퍼 비우기와 같은 정리 태스크를 트리거하는 데 사용됩니다. lambda_runtime에서는 정상 종료 신호 처리 구성을 단순화하는 도우미를 제공합니다(spawn_graceful_shutdown_handler()). 실행 환경 수명 주기에 대한 자세한 내용은 Lambda 실행 환경 수명 주기 이해 섹션을 참조하세요.

종속성 버전

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

  • lambda_runtime: concurrency-tokio 특성이 활성화된 버전 1.1.1 이상

  • 지원되는 최소 Rust 버전(MSRV)은 1.84.0입니다.