

# Lambda를 사용하여 코드 실행
<a name="concepts-how-lambda-runs-code"></a>

Lambda 함수를 작성할 경우, 고유한 서버리스 환경에서 실행되는 코드를 생성하게 됩니다. Lambda가 실제로 코드를 실행하는 방법을 이해하려면 두 가지 주요 측면, 즉 코드가 Lambda와 상호 작용하는 방식을 정의하는 프로그래밍 모델과 Lambda가 코드의 런타임 환경을 관리하는 방법을 결정하는 실행 환경 수명 주기를 알아야 합니다.

## Lambda 프로그래밍 모델
<a name="concepts-progmodel-overview"></a>

프로그래밍 모델은 Python, Java로 작성하거나 지원되는 다른 언어로 작성하는 경우와 무관하게 Lambda가 코드와 작동하는 방식에 대한 공통 규칙 세트로 작동합니다. 프로그래밍 모델에는 런타임과 핸들러가 포함됩니다.

**표준 함수:**

1. Lambda는 이벤트를 수신합니다.

1. Lambda는 런타임을 사용하여 코드가 사용할 수 있는 형식으로 이벤트를 준비합니다.

1. 런타임은 형식이 지정된 이벤트를 핸들러로 전송합니다.

1. 핸들러는 작성한 코드를 사용하여 이벤트를 처리합니다.

**지속성 함수:**

1. Lambda의 이벤트 수신

1. 런타임은 이벤트와 DurableContext를 모두 준비

1. 핸들러가 수행할 수 있는 작업은 다음과 같습니다.
   + 자동 체크포인트 지정을 통한 단계 처리
   + 리소스를 사용하지 않고 실행 일시 중지
   + 마지막으로 성공한 체크포인트에서 재개
   + 단계 사이에 상태 유지

이 모델의 필수 요소는 Lambda가 코드에서 처리할 이벤트를 보내는 *핸들러*입니다. 이를 코드의 진입점으로 생각하세요. Lambda가 이벤트를 수신하면 이 이벤트와 일부 컨텍스트 정보가 핸들러에 전달됩니다. 그런 다음, 핸들러는 코드를 실행하여 이러한 이벤트를 처리합니다. 예를 들어 Amazon S3에 업로드되면 파일을 읽거나, 이미지를 분석하거나, 데이터베이스를 업데이트할 수 있습니다. 코드가 이벤트 처리를 마치면 핸들러가 다음 이벤트를 처리할 준비가 된 것입니다.

## Lambda 실행 모델
<a name="concepts-exec-env-overview"></a>

프로그래밍 모델은 Lambda가 코드와 상호 작용하는 방식을 정의하지만, 실행 환경은 Lambda가 함수를 실제로 실행하는 곳입니다. 이는 함수에 사용하도록 특별히 생성된 안전하고 격리된 컴퓨팅 공간입니다.

**각 환경은 표준 함수와 지속성 함수에 따라 달라지는 수명 주기를 따릅니다.**

**표준 함수(최대 15분):**

1. **초기화:** 환경 설정 및 코드 로드

1. **간접 호출:** 함수 코드의 단일 실행

1. **종료:** 환경 정리

**지속성 함수(최대 1년):**

1. **초기화:** 환경 및 지속성 상태 설정

1. **간접 호출:** 자동 체크포인트 지정을 포함한 여러 단계

1. **대기 상태:** 리소스 소비 없이 실행 일시 중지

1. **재개:** 마지막 체크포인트에서 다시 시작

1. **종료:** 지속성 상태 정리

이 환경은 함수 실행의 중요한 측면을 처리합니다. 이는 함수에 메모리와 임시 스토리지용 `/tmp` 디렉터리를 제공합니다. **지속성 함수의 경우 다음도 관리합니다.**
+ 단계 간 자동 상태 지속성
+ 체크포인트 스토리지 및 복구
+ 대기 상태 조정
+ 장기 실행에서의 진행 상황 추적

# Lambda 프로그래밍 모델에 대한 이해
<a name="foundation-progmodel"></a>

Lambda는 최대 15분 동안 실행되는 표준 함수와 최대 1년 동안 실행되는 지속성 함수라는 2가지 프로그래밍 모델을 제공합니다. 2가지 모두 핵심 개념을 공유하지만 지속성 함수는 장기 실행 상태 저장 워크플로를 위한 기능을 추가합니다.

Lambda는 모든 런타임에 공통적인 프로그래밍 모델을 제공합니다. 프로그래밍 모델은 코드와 Lambda 시스템 간의 인터페이스를 정의합니다. 함수 구성에서 *핸들러*를 정의하여 Lambda에게 함수의 진입점을 알려줍니다. 런타임은 호출 *이벤트*와 *컨텍스트*(예: 함수 이름, 요청 ID)를 포함하는 핸들러로 객체를 전달합니다.

**지속성 함수의 경우 핸들러는 다음을 제공하는 DurableContext 객체도 수신합니다.**
+ step()을 통한 체크포인트 지정 기능
+ wait() 및 waitForCallback()을 통한 대기 상태 관리
+ 간접 호출 간 자동 상태 지속성

핸들러가 첫 번째 이벤트 처리를 완료하면 런타임이 다른 이벤트를 보냅니다. 지속성 함수의 경우 핸들러는 단계 간 실행을 일시 중지할 수 있으며, Lambda는 함수가 재개될 때 상태를 자동으로 저장 및 복원합니다. 함수의 클래스가 메모리에 유지되므로, *초기화 코드*에서 핸들러 메서드 외부에서 선언된 클라이언트 및 변수를 재사용할 수 있습니다. 후속 이벤트에 대한 처리 시간을 절약하려면 초기화 중에 AWS SDK 클라이언트와 같은 재사용 가능한 리소스를 생성합니다. 초기화된 후에는 함수의 각 인스턴스가 수천 개의 요청을 처리할 수 있습니다.

또한 함수는 여러 간접 호출에 사용할 수 있는 임시 캐시인 `/tmp` 디렉터리의 로컬 스토리지에 액세스할 수 있습니다. 자세한 내용은 [실행 환경](lambda-runtime-environment.md) 섹션을 참조하세요.

[AWS X-Ray 추적](services-xray.md)이 활성화된 경우 런타임이 초기화와 실행에 대해 별도의 하위 세그먼트를 기록합니다.

런타임은 함수에서 로깅 출력을 캡처하여 Amazon CloudWatch Logs로 전송합니다. 런타임은 함수의 출력을 로깅하는 것 외에도 호출이 시작되고 끝날 때 항목을 로깅합니다. 여기에는 요청 ID, 요금이 청구되는 소요 시간, 초기화 소요 시간 및 기타 세부 정보가 들어 있는 보고서 로그가 포함됩니다. 함수에서 오류가 발생하는 경우, 런타임은 해당 오류를 간접 호출자에게 반환합니다.

**참고**  
로깅에는 [CloudWatch Logs 할당량](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/cloudwatch_limits_cwl.html)이 적용됩니다.. 로그 데이터는 조절로 인해, 또는 경우에 따라 함수의 인스턴스가 중지될 때 손실될 수 있습니다.

**지속성 함수의 주요 차이점:**
+ 단계 간에 상태가 자동으로 유지
+ 함수는 리소스를 사용하지 않고 실행의 일시 중지 가능
+ 실패 시 단계가 자동으로 재시도
+ 체크포인트를 통해 진행 상황 추적

Lambda는 수요가 증가하면 추가 인스턴스를 실행하고 수요가 감소하면 인스턴스를 중지하여 함수 규모를 조정합니다. 이 모델은 다음과 같은 애플리케이션 아키텍처의 변형을 초래합니다.
+ 달리 지정되지 않는 한, 수신 요청은 비순차적으로, 또는 동시에 처리될 수 있습니다.
+ 오래 지속되는 함수의 인스턴스를 사용하지 말고 대신 애플리케이션의 상태를 다른 곳에 저장하세요.
+ 로컬 스토리지 및 클래스 수준 객체를 사용하여 성능을 강화할 수 있지만, 실행 환경으로 전송하는 배포 패키지의 크기와 데이터의 양을 최소로 유지하세요.

다음 장에서는 선호하는 프로그래밍 언어의 프로그래밍 모델을 실습 과정을 겸하여 소개합니다.
+ [Node.js를 사용하여 Lambda 함수 빌드](lambda-nodejs.md)
+ [Python을 사용하여 Lambda 함수 빌드](lambda-python.md)
+ [Ruby를 사용하여 Lambda 함수 빌드](lambda-ruby.md)
+ [Java를 사용하여 Lambda 함수 빌드](lambda-java.md)
+ [Go를 사용하여 Lambda 함수 빌드](lambda-golang.md)
+ [C\$1을 사용하여 Lambda 함수 빌드](lambda-csharp.md)
+ [PowerShell을 사용하여 Lambda 함수 빌드](lambda-powershell.md)

# Lambda 실행 환경 수명 주기 이해
<a name="lambda-runtime-environment"></a>

Lambda 실행 환경은 표준 함수(최대 15분)와 지속성 함수(최대 1년)를 모두 지원합니다. 둘 다 동일한 기본 수명 주기를 공유하지만 지속성 함수는 장기 실행 워크플로의 상태 관리 기능을 추가합니다.

 Lambda는 안전하고 격리된 런타임 환경을 제공하는 실행 환경에서 함수를 호출합니다. 실행 환경은 함수를 실행하는 데 필요한 리소스를 관리합니다. 또한 실행 환경은 함수의 런타임 및 함수와 관련된 모든 [외부 익스텐션](lambda-extensions.md)에 대한 수명 주기 지원을 제공합니다.

**지속성 함수의 경우 실행 환경에 포함되는 추가 구성 요소:**
+ 단계 간 상태 지속성
+ 체크포인트 관리
+ 대기 상태 조정
+ 진행 상황 추적

**Lambda 관리형 인스턴스 실행 환경**  
[Lambda 관리형 인스턴스](lambda-managed-instances-execution-environment.md)를 사용하는 경우 실행 환경은 Lambda(기본값) 함수와 비교할 때 중요한 차이가 있습니다. 관리형 인스턴스는 동시 간접 호출을 지원하고, 다른 수명 주기 모델을 사용하고, 고객 소유 인프라에서 실행됩니다. 관리형 인스턴스 실행 환경에 대한 자세한 내용은 [Lambda 관리형 인스턴스 실행 환경 이해](lambda-managed-instances-execution-environment.md) 항목을 참조하세요.

함수의 런타임은 [런타임 API](runtimes-api.md)를 사용하여 Lambda와 통신합니다. 익스텐션은 [익스텐션 API](runtimes-extensions-api.md)를 사용하여 Lambda와 통신합니다. 또한 확장은 [텔레메트리 API](telemetry-api.md)를 사용하여 함수의 로그 메시지와 기타 텔레메트리 데이터를 수신할 수 있습니다.



![\[실행 환경의 아키텍처 다이어그램.\]](http://docs.aws.amazon.com/ko_kr/lambda/latest/dg/images/telemetry-api-concept-diagram.png)


Lambda 함수를 생성할 때 함수에서 허용된 메모리 용량 및 최대 실행 시간 같은 구성 정보를 지정합니다. Lambda는 이 정보를 사용하여 실행 환경을 설정합니다.

함수의 런타임 및 각 외부 익스텐션은 실행 환경 내에서 실행되는 프로세스입니다. 권한, 리소스, 자격 증명 및 환경 변수는 함수와 익스텐션 간에 공유됩니다.

**Topics**
+ [

## Lambda 실행 환경 수명 주기
](#runtimes-lifecycle)
+ [

## 콜드 스타트 및 지연 시간
](#cold-start-latency)
+ [

## 프로비저닝된 동시성으로 콜드 스타트 감소
](#cold-starts-pc)
+ [

## 정적 초기화 최적화
](#static-initialization)

## Lambda 실행 환경 수명 주기
<a name="runtimes-lifecycle"></a>

![\[Lambda 수명 주기 단계: 초기화, 간접 호출, 종료\]](http://docs.aws.amazon.com/ko_kr/lambda/latest/dg/images/Overview-Successful-Invokes.png)


각 단계는 Lambda가 런타임 및 등록된 모든 익스텐션에 전송하는 이벤트로 시작됩니다. 런타임 및 각 익스텐션이 `Next` API 요청을 전송하여 완료를 나타냅니다. 런타임 및 각 익스텐션이 완료되고 대기 중인 이벤트가 없으면 Lambda는 실행 환경을 중지합니다.

**다음은 지속성 함수의 수명 주기 단계입니다.**
+ **초기화:** 표준 초기화 및 지속 상태 설정
+ **간접 호출:** 자동 체크포인트 지정을 사용하여 여러 단계 실행 포함 가능
+ **대기:** 함수는 리소스를 사용하지 않고 실행의 일시 중지 가능
+ **재개:** 함수가 마지막 체크포인트에서 다시 시작
+ **종료:** 지속 상태 및 리소스 정리

**Topics**
+ [

### 초기화 단계
](#runtimes-lifecycle-ib)
+ [

### Init 단계 중 실패
](#runtimes-lifecycle-init-errors)
+ [

### 복원 단계(Lambda SnapStart만 해당)
](#runtimes-lifecycle-restore)
+ [

### 간접 호출 단계
](#runtimes-lifecycle-invoke)
+ [

### 간접 호출 단계 중 실패
](#runtimes-lifecycle-invoke-with-errors)
+ [

### 종료 단계
](#runtimes-lifecycle-shutdown)

### 초기화 단계
<a name="runtimes-lifecycle-ib"></a>

`Init` 단계에서 Lambda는 다음 세 가지 작업을 수행합니다.
+ 모든 익스텐션 시작(`Extension init`)
+ 런타임 부트스트랩(`Runtime init`)
+ 함수의 정적 코드 실행(`Function init`)
+ 모든 체크포인트 전 [런타임 후크](snapstart-runtime-hooks.md) 실행(Lambda SnapStart만 해당)

`Init` 단계는 런타임 및 모든 익스텐션이 `Next` API 요청을 전송하여 준비되었음을 알린 후에 종료됩니다. `Init` 단계는 10초로 제한됩니다. 세 작업이 모두 10초 이내에 완료되지 않으면 Lambda는 첫 번째 함수 호출 시 구성된 함수 타임아웃으로 `Init` 단계를 다시 시도합니다.

[Lambda SnapStart](snapstart.md)가 활성화되면 함수 버전을 게시할 때 `Init` 단계가 발생합니다. Lambda는 초기화된 실행 환경의 메모리 및 디스크 상태 스냅샷을 저장하고 암호화된 스냅샷을 유지하며 짧은 지연 시간으로 액세스할 수 있도록 스냅샷을 캐싱합니다. 체크포인트 이전의 [런타임 후크](snapstart-runtime-hooks.md)가 있는 경우 코드는 `Init` 단계가 끝날 때 실행됩니다.

**참고**  
10초 제한 시간은 프로비저닝 동시성, SnapStart 또는 Lambda 관리형 인스턴스를 사용하는 함수에는 적용되지 않습니다. 프로비저닝 동시성, SnapStart 및 관리형 인스턴스 함수의 경우 초기화 코드를 최대 15분 동안 실행할 수 있습니다. 시간 제한은 130초 또는 구성된 함수 제한 시간(최대 900초) 중 더 높은 값입니다.

[프로비저닝된 동시성](https://docs.aws.amazon.com/lambda/latest/dg/provisioned-concurrency.html)을 사용하면 함수에 대한 PC 설정을 구성할 때 Lambda가 실행 환경을 초기화합니다. 또한 Lambda는 간접 호출에 앞서 초기화된 실행 환경을 항상 사용할 수 있도록 합니다. 함수의 간접 호출 단계와 초기화 단계 사이에 시간 격차가 발생할 수 있습니다. 함수의 런타임 및 메모리 구성에 따라 초기화된 실행 환경에서 첫 번째 간접 호출 시 가변적 지연 시간이 나타날 수도 있습니다.

온디맨드 동시성을 사용하는 함수의 경우 Lambda는 간접 호출 요청에 앞서 실행 환경을 초기화하는 경우가 있습니다. 이 경우 함수의 초기화 단계와 간접 호출 단계 사이에 시간 격차가 발생할 수 있습니다. 이 동작에 의존하지 않는 것이 좋습니다.

### Init 단계 중 실패
<a name="runtimes-lifecycle-init-errors"></a>

`Init` 단계 중에 함수가 충돌하거나 시간이 초과되면 Lambda는 `INIT_REPORT` 로그에 오류 정보를 생성합니다.

**Example — 타임아웃에 대한 INIT\$1REPORT 로그**  

```
INIT_REPORT Init Duration: 1236.04 ms Phase: init Status: timeout
```

**Example — 확장 실패에 대한 INIT\$1REPORT 로그**  

```
INIT_REPORT Init Duration: 1236.04 ms Phase: init Status: error Error Type: Extension.Crash
```

`Init` 단계가 성공하면 [SnapStart](snapstart.md) 또는 [프로비저닝된 동시성](provisioned-concurrency.md)이 활성화되지 않은 한 Lambda는 `INIT_REPORT` 로그를 내보내지 않습니다. SnapStart 및 프로비저닝된 동시성 함수는 항상 `INIT_REPORT`를 내보냅니다. 자세한 내용은 [Lambda SnapStart 모니터링](snapstart-monitoring.md) 섹션을 참조하세요.

### 복원 단계(Lambda SnapStart만 해당)
<a name="runtimes-lifecycle-restore"></a>

[SnapStart](snapstart.md) 함수를 처음 간접 호출하고 함수가 스케일 업되면 Lambda는 이 함수를 처음부터 초기화하는 대신 유지된 스냅샷에서 새 실행 환경을 재개합니다. 복원 후 [런타임 후크](snapstart-runtime-hooks.md)가 있는 경우 코드는 `Restore` 단계가 끝날 때 실행됩니다. 복원 후 런타임 후크 지속 시간에 대해 요금이 청구됩니다. 런타임이 로드되고 복원 후 런타임 후크가 제한 시간(10초) 내에 완료되어야 합니다. 그렇지 않으면 SnapStartTimeoutException이 발생합니다. `Restore` 단계가 완료되면 Lambda가 함수 핸들러([간접 호출 단계](#runtimes-lifecycle-invoke))를 간접적으로 간접 호출합니다.

#### 복원 단계 중 실패
<a name="runtimes-lifecycle-restore-errors"></a>

`Restore` 단계가 실패하면 Lambda는 `RESTORE_REPORT` 로그에 오류 정보를 생성합니다.

**Example — 타임아웃에 대한 RESTORE\$1REPORT 로그**  

```
RESTORE_REPORT Restore Duration: 1236.04 ms Status: timeout
```

**Example — 런타임 후크 실패에 대한 RESTORE\$1REPORT 로그**  

```
RESTORE_REPORT Restore Duration: 1236.04 ms Status: error Error Type: Runtime.ExitError
```

`RESTORE_REPORT` log에 대한 자세한 내용은 [Lambda SnapStart 모니터링](snapstart-monitoring.md)을 참조하십시오.

### 간접 호출 단계
<a name="runtimes-lifecycle-invoke"></a>

`Next` API 요청에 대한 응답으로 Lambda 함수가 간접 호출되면 Lambda는 런타임과 각 익스텐션에 `Invoke` 이벤트를 전송합니다.

함수의 제한 시간 설정은 전체 `Invoke` 단계의 기간을 제한합니다. 예를 들어 함수 제한 시간을 360초로 설정하면 함수와 모든 익스텐션이 360초 내에 완료되어야 합니다. 독립적인 간접 호출 후 단계는 없습니다. 기간은 모든 호출 시간(런타임 \$1 익스텐션)의 합계이며 함수와 모든 익스텐션의 실행이 완료될 때까지 계산되지 않습니다.

간접 호출 단계는 런타임 및 모든 익스텐션이 `Next` API 요청을 전송하여 완료되었음을 알린 후에 종료됩니다.

### 간접 호출 단계 중 실패
<a name="runtimes-lifecycle-invoke-with-errors"></a>

`Invoke` 단계 중에 Lambda 함수가 충돌하거나 시간이 초과되면 Lambda는 실행 환경을 재설정합니다. 다음 다이어그램은 간접 호출 실패 시 Lambda 실행 환경 동작을 보여줍니다.

![\[실행 환경 예시: 초기화, 간접 호출, 오류가 있는 간접 호출, 간접 호출, 종료\]](http://docs.aws.amazon.com/ko_kr/lambda/latest/dg/images/Overview-Invoke-with-Error.png)


이전 다이어그램에서
+ 첫 번째 단계는 오류 없이 실행되는 **INIT** 단계입니다.
+ 두 번째 단계는 오류 없이 실행되는 **INVOKE** 단계입니다.
+ 어느 시점에서 함수에 간접 호출 실패가 발생한다고 가정해 보겠습니다. 일반적인 원인으로는 함수 시간 초과, 런타임 오류, 메모리 부족, VPC 연결 문제, 권한 오류, 동시성 제한, 다양한 구성 문제 등이 있습니다. 가능한 간접 호출 실패의 전체 목록은 [Lambda의 호출 문제 해결](troubleshooting-invocation.md) 섹션을 참조하세요. **INVOKE WITH ERROR**라고 표시된 세 번째 단계가 이 시나리오를 보여줍니다. 이 경우 Lambda 서비스가 재설정을 수행합니다. 재설정은 `Shutdown` 이벤트처럼 동작합니다. 먼저 Lambda는 런타임을 종료한 다음 등록된 각 외부 익스텐션에 `Shutdown` 이벤트를 전송합니다. 이벤트에는 종료 이유가 포함됩니다. 이 환경이 새 호출에 사용되는 경우 Lambda는 익스텐션과 런타임을 다음 호출과 함께 다시 초기화합니다.

  Lambda 재설정으로 다음 초기화 단계 전에 `/tmp` 디렉터리의 내용이 지워지지 않는다는 점에 유의하세요. 이 동작은 일반 종료 단계와 동일합니다.
**참고**  
AWS는 현재 Lambda 서비스에 대한 변경 사항을 구현하고 있습니다. 이러한 변경으로 인해, AWS 계정의 여러 Lambda 함수에서 내보내는 시스템 로그 메시지와 추적 세그먼트의 구조와 내용 간에 약간의 차이가 있을 수 있습니다.  
함수의 시스템 로그 구성이 일반 텍스트로 설정된 경우, 이 변경은 함수에서 간접 호출 실패가 발생할 때 CloudWatch Logs에 캡처되는 로그 메시지에 영향을 줍니다. 다음 예는 이전 형식과 새 형식의 로그 출력을 모두 보여줍니다.  
이러한 변경 사항은 앞으로 몇 주 동안 구현되며, 중국 및 GovCloud 리전을 제외한 모든 AWS 리전의 모든 기능은 새로운 형식의 로그 메시지 및 추적 세그먼트를 사용하도록 전환됩니다.

    
**Example CloudWatch Logs 로그 출력(런타임 또는 확장 충돌) - 이전 스타일**  

  ```
  START RequestId: c3252230-c73d-49f6-8844-968c01d1e2e1 Version: $LATEST
  RequestId: c3252230-c73d-49f6-8844-968c01d1e2e1 Error: Runtime exited without providing a reason
  Runtime.ExitError
  END RequestId: c3252230-c73d-49f6-8844-968c01d1e2e1
  REPORT RequestId: c3252230-c73d-49f6-8844-968c01d1e2e1 Duration: 933.59 ms Billed Duration: 934 ms Memory Size: 128 MB Max Memory Used: 9 MB
  ```  
**Example CloudWatch Logs 로그 출력(함수 제한 시간) - 이전 스타일**  

  ```
  START RequestId: b70435cc-261c-4438-b9b6-efe4c8f04b21 Version: $LATEST
  2024-03-04T17:22:38.033Z b70435cc-261c-4438-b9b6-efe4c8f04b21 Task timed out after 3.00 seconds
  END RequestId: b70435cc-261c-4438-b9b6-efe4c8f04b21
  REPORT RequestId: b70435cc-261c-4438-b9b6-efe4c8f04b21 Duration: 3004.92 ms Billed Duration: 3117 ms Memory Size: 128 MB Max Memory Used: 33 MB Init Duration: 111.23 ms
  ```

  CloudWatch 로그의 새 형식에는 `REPORT` 줄에 `status` 필드가 추가로 포함됩니다. 런타임 또는 확장 충돌이 발생하는 경우, 해당 `REPORT` 줄에는 `ErrorType` 필드도 포함됩니다.

    
**Example CloudWatch Logs 로그 출력(런타임 또는 확장 충돌) - 새 스타일**  

  ```
  START RequestId: 5b866fb1-7154-4af6-8078-6ef6ca4c2ddd Version: $LATEST
  END RequestId: 5b866fb1-7154-4af6-8078-6ef6ca4c2ddd
  REPORT RequestId: 5b866fb1-7154-4af6-8078-6ef6ca4c2ddd Duration: 133.61 ms Billed Duration: 214 ms Memory Size: 128 MB Max Memory Used: 31 MB Init Duration: 80.00 ms Status: error Error Type: Runtime.ExitError
  ```  
**Example CloudWatch Logs 로그 출력(함수 제한 시간) - 새 스타일**  

  ```
  START RequestId: 527cb862-4f5e-49a9-9ae4-a7edc90f0fda Version: $LATEST
  END RequestId: 527cb862-4f5e-49a9-9ae4-a7edc90f0fda
  REPORT RequestId: 527cb862-4f5e-49a9-9ae4-a7edc90f0fda Duration: 3016.78 ms Billed Duration: 3101 ms Memory Size: 128 MB Max Memory Used: 31 MB Init Duration: 84.00 ms Status: timeout
  ```
+ 네 번째 단계는 간접 호출 실패 직후의 **간접 호출** 단계를 나타냅니다. 여기서 Lambda는 **INIT** 단계를 다시 실행하여 환경을 다시 초기화합니다. 이를 억제된 초기화라고 합니다.** 억제된 초기화가 발생하는 경우 Lambda는 CloudWatch 로그에 추가 **INIT** 단계를 명시적으로 보고하지는 않습니다. 대신 REPORT 줄의 지속 시간에 추가 **INIT **기간 \$1 간접 호출**** 기간이 포함되어 있음을 알 수 있습니다. 예를 들어 CloudWatch에 다음과 같은 로그가 표시되어 있다고 가정하겠습니다.

  ```
  2022-12-20T01:00:00.000-08:00 START RequestId: XXX Version: $LATEST 
  2022-12-20T01:00:02.500-08:00 END RequestId: XXX 
  2022-12-20T01:00:02.500-08:00 REPORT RequestId: XXX Duration: 3022.91 ms 
  Billed Duration: 3000 ms Memory Size: 512 MB Max Memory Used: 157 MB
  ```

  이 예제에서 REPORT 타임스탬프와 START 타임스탬프 간의 차이는 2.5초입니다. 이는 Lambda가 수행한 추가 **INIT**(억제된 초기화)를 고려하지 않기 때문에 보고된 지속 시간인 3022.91 밀리초와 일치하지 않습니다. 이 예시에서는 실제 **간접 호출** 단계에 2.5초가 걸렸다고 추론할 수 있습니다.

  이 동작에 대해 더 자세히 알아보려면 [텔레메트리 API를 사용하여 확장의 실시간 텔레메트리 데이터에 액세스](telemetry-api.md)을 사용하면 됩니다. Telemetry API는 간접 호출 단계 사이에 억제된 초기화가 발생할 때마다 `INIT_START`, `INIT_RUNTIME_DONE`, `INIT_REPORT`, `phase=invoke` 이벤트를 내보냅니다.
+ 다섯 번째 단계는 오류 없이 실행되는 **SHUTDOWN** 단계를 나타냅니다.

### 종료 단계
<a name="runtimes-lifecycle-shutdown"></a>

Lambda는 런타임을 종료하려고 할 때 `Shutdown` 이벤트를 등록된 각 외부 익스텐션에 전송합니다. 익스텐션은 이 시간 동안 최종 정리 작업을 수행할 수 있습니다. `Shutdown` 이벤트는 `Next` API 요청에 대한 응답입니다.

**기간 제한**: `Shutdown` 단계의 최대 기간은 등록된 익스텐션 구성에 따라 다릅니다.
+ 0밀리초 - 등록된 익스텐션이 없는 함수
+ 500밀리초 - 등록된 내부 익스텐션이 하나 있는 함수
+ 2,000밀리초 - 등록된 외부 익스텐션이 하나 이상 있는 함수

런타임 또는 익스텐션이 제한 시간 내에 `Shutdown` 이벤트에 응답하지 않는 경우 Lambda는 `SIGKILL` 신호를 사용하여 프로세스를 종료합니다.

함수와 모든 익스텐션이 완료된 후 Lambda는 다른 함수 호출을 예상하여 일정 시간 동안 실행 환경을 유지합니다. 그러나 Lambda는 몇 시간마다 실행 환경을 종료하여 런타임 업데이트 및 유지 관리를 허용하며, 이는 지속적으로 간접 호출되는 함수에 대해서도 동일합니다. 실행 환경이 무기한 지속될 것이라고 가정하면 안 됩니다. 자세한 내용은 [함수에서 상태 비저장 구현](concepts-application-design.md#statelessness-functions) 섹션을 참조하세요.

함수가 다시 간접적으로 호출되면 Lambda는 재사용을 위해 환경을 재개합니다. 실행 환경을 재사용하는 것은 다음과 같은 의미를 가집니다.
+ 함수의 핸들러 메서드 외부에서 선언된 객체는 함수가 다시 간접 호출될 때 추가로 최적화가 되도록 초기화된 상태로 유지됩니다. 예를 들어 Lambda 함수가 연결을 재설정하는 대신 데이터베이스 연결을 설정하면 원래 연결이 후속 호출에 사용됩니다. 코드에 로직을 추가하여 연결을 새로 생성하기에 앞서 연결이 이미 존재하는지 확인하는 것이 좋습니다.
+ 각 실행 환경은 `/tmp` 디렉터리에 512MB에서 10,240MB 사이 1MB 단위로 디스크 공간을 제공합니다. 디렉터리 콘텐츠는 실행 환경이 일시 중지되어도 그대로 유지되기 때문에 일시적인 캐시를 여러 호출에서 사용할 수 있습니다. 코드를 추가하여 캐시에 저장한 데이터가 포함되어 있는지 확인할 수 있습니다. 배포 크기 제한에 대한 자세한 내용은 [Lambda 할당량Lambda 할당량](gettingstarted-limits.md) 섹션을 참조하세요.
+ Lambda 함수에 의해 초기화되었고 함수 종료 시 완료되지 않은 백그라운드 프로세스 또는 콜백은 Lambda가 실행 환경을 재사용하는 경우에 재개됩니다. 코드가 종료되려면 먼저 코드의 백그라운드 프로세스 또는 콜백이 완료되어야 합니다.

## 콜드 스타트 및 지연 시간
<a name="cold-start-latency"></a>

Lambda가 Lambda API를 통해 함수를 실행하라는 요청을 수신하면 서비스는 먼저 실행 환경을 준비합니다. 이 초기화 단계에서 서비스는 코드를 다운로드하고, 환경을 시작하고, 기본 핸들러 외부에서 모든 초기화 코드를 실행합니다. 마지막으로 Lambda는 핸들러 코드를 실행합니다.

![\[성능 최적화 그림 1\]](http://docs.aws.amazon.com/ko_kr/lambda/latest/dg/images/perf-optimize-figure-1.png)


이 다이어그램에서 코드를 다운로드하고 환경을 설정하는 처음 두 단계는 '콜드 스타트'라고 불리기도 합니다. [이 기간에는 요금이 부과되며](https://aws.amazon.com/blogs/compute/aws-lambda-standardizes-billing-for-init-phase/) 전체 간접 호출 기간에 지연 시간이 추가됩니다.

간접 호출이 완료되면 실행 환경이 동결됩니다. 리소스 관리 및 성능을 개선하기 위해 Lambda는 일정 기간 동안 실행 환경을 유지합니다. 이 기간 동안 동일한 함수에 대해 또 다른 요청이 도착하면 Lambda가 환경을 재사용할 수 있습니다. 실행 환경이 이미 완전히 설정되어 있으므로 이 두 번째 요청은 일반적으로 더 빨리 완료됩니다. 이를 '웜 스타트'라고 합니다.

콜드 스타트는 일반적으로 간접 호출의 1% 미만에서 발생합니다. 콜드 스타트 지속 시간은 100밀리초 미만에서 1초 넘게까지 다양합니다. 일반적으로 콜드 스타트는 프로덕션 워크로드보다 개발 및 테스트 함수에서 더 흔합니다. 일반적으로 개발 및 테스트 함수에서 간접 호출 횟수가 더 적기 때문입니다.

## 프로비저닝된 동시성으로 콜드 스타트 감소
<a name="cold-starts-pc"></a>

워크로드에 대해 예측 가능한 함수 시작 시간이 필요한 경우 가능한 지연 시간을 최소화하려면 [프로비저닝된 동시성](provisioned-concurrency.md)을 사용하는 것이 좋습니다. 이 기능은 실행 환경을 미리 초기화하여 콜드 스타트를 줄입니다.

예를 들어 프로비저닝된 동시성이 6인 함수에서는 6개의 실행 환경이 미리 워밍됩니다.

![\[성능 최적화 그림 4\]](http://docs.aws.amazon.com/ko_kr/lambda/latest/dg/images/perf-optimize-figure-4.png)


## 정적 초기화 최적화
<a name="static-initialization"></a>

정적 초기화는 함수에서 핸들러 코드 실행이 시작되기 전에 수행됩니다. 이는 기본 핸들러 외부에 있는 사용자가 제공하는 초기화 코드입니다. 이 코드는 라이브러리 및 종속성을 가져오고 구성을 설정하며 다른 서비스에 대한 연결을 초기화하는 데 자주 사용됩니다.

다음 Python 예제에서는 간접 호출 중 `lambda_handler` 함수가 실행되기 전에 초기화 단계에서 모듈을 가져오고 구성하며 Amazon S3 클라이언트를 생성하는 방법을 보여줍니다.

```
import os
import json
import cv2
import logging
import boto3

s3 = boto3.client('s3')
logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(event, context):

  # Handler logic...
```

함수 실행 전 지연 시간에 가장 많이 기여하는 요인은 초기화 코드입니다. 이 코드는 새 실행 환경이 처음 생성될 때 실행됩니다. 간접 호출이 웜 실행 환경을 사용하는 경우 초기화 코드가 다시 실행되지 않습니다. 초기화 코드 지연 시간에 영향을 미치는 요인은 다음과 같습니다.
+ 가져온 라이브러리 및 종속 항목과 Lambda 계층 관점에서 함수 패키지의 크기.
+ 코드 및 초기화 작업의 양.
+ 연결 및 기타 리소스를 설정할 때 라이브러리 및 기타 서비스의 성능.

정적 초기화 지연 시간을 최적화하기 위해 개발자가 수행할 수 있는 여러 단계가 있습니다. 함수에 객체 및 연결이 많은 경우 단일 함수를 여러 특수 함수로 리아키텍팅할 수 있습니다. 이들은 개별적으로 더 작으며 각각 초기화 코드가 적습니다.

함수는 필요한 라이브러리 및 종속 항목만 가져와야 합니다. 예를 들어 AWS SDK에서 Amazon DynamoDB만 사용하는 경우 전체 SDK 대신 개별 서비스가 필요할 수 있습니다. 다음 세 가지 예제를 비교합니다.

```
// Instead of const AWS = require('aws-sdk'), use:
const DynamoDB = require('aws-sdk/clients/dynamodb')

// Instead of const AWSXRay = require('aws-xray-sdk'), use:
const AWSXRay = require('aws-xray-sdk-core')

// Instead of const AWS = AWSXRay.captureAWS(require('aws-sdk')), use:
const dynamodb = new DynamoDB.DocumentClient()
AWSXRay.captureAWSClient(dynamodb.service)
```

정적 초기화는 함수가 동일한 실행 환경에 대한 여러 간접 호출을 통해 연결을 재사용할 수 있도록 데이터베이스 연결을 여는 데 가장 적합한 위치이기도 합니다. 그러나 함수의 특정 실행 경로에서만 사용되는 객체가 많을 수 있습니다. 이 경우 전역 범위에서 변수를 지연 로드하여 정적 초기화 지속 시간을 줄일 수 있습니다.

컨텍스트별 정보에 대해서는 전역 변수를 사용하지 마세요. 함수에 단일 간접 호출의 수명 동안에만 사용되고 다음 간접 호출을 위해 재설정되는 전역 변수가 있는 경우 핸들러에 로컬로 존재하는 변수 범위를 사용합니다. 그러면 여러 간접 호출에서 전역 변수 누출을 방지하고 정적 초기화 성능도 개선됩니다.