

# Lambda SnapStart를 사용하여 시작 성능 개선
<a name="snapstart"></a>

Lambda SnapStart는 일반적으로 함수 코드를 변경하지 않고도 1초 미만의 시작 성능을 제공할 수 있습니다. SnapStart를 사용하면 리소스를 프로비저닝하거나 복잡한 성능 최적화를 구현하지 않고도 응답성 및 확장성이 뛰어난 애플리케이션을 더 쉽게 빌드할 수 있습니다.

시작 지연 시간(콜드 스타트 시간이라고도 함)이 발생하는 가장 큰 원인은 Lambda가 함수를 초기화하는 데 시간을 소비하기 때문입니다. 여기에는 함수 코드 로드 시간, 런타임 시작 시간, 함수 코드 초기화 시간이 포함됩니다. SnapStart를 사용하면 함수 버전을 게시할 때 Lambda가 함수를 초기화합니다. Lambda는 초기화된 [실행 환경](lambda-runtime-environment.md)의 메모리 및 디스크 상태에대한 [Firecracker microVM](https://aws.amazon.com/blogs/opensource/firecracker-open-source-secure-fast-microvm-serverless/) 스냅샷을 생성하고 스냅샷을 암호화하며 지능적으로 캐싱하여 검색 지연 시간을 최적화합니다.

복원력을 보장하기 위해 Lambda에서는 각 스냅샷의 여러 사본을 유지합니다. Lambda에서는 최신 런타임 및 보안 업데이트를 사용하여 스냅샷 및 해당 사본을 자동으로 패치합니다. 함수 버전을 처음 간접 호출하는 경우와 간접 호출이 스케일 업되는 경우 Lambda는 실행 환경을 처음부터 초기화하는 대신 캐싱된 스냅샷에서 새 실행 환경을 재개하여 시작 지연 시간을 개선합니다.

**중요**  
애플리케이션에서 상태의 고유성이 중요한 경우 함수 코드를 평가하여 스냅샷 작업에 복원력이 있는지 확인해야 합니다. 자세한 내용은 [Lambda SnapStart를 사용한 고유성 처리](snapstart-uniqueness.md) 섹션을 참조하세요.

**Topics**
+ [SnapStart를 사용하는 경우](#snapstart-use-cases)
+ [지원 기능 및 제한 사항](#snapstart-runtimes)
+ [지원되는 리전](#snapstart-supported-regions)
+ [호환성 고려 사항](#snapstart-compatibility)
+ [SnapStart 요금](#snapstart-pricing)
+ [Lambda SnapStart 활성화 및 관리](snapstart-activate.md)
+ [Lambda SnapStart를 사용한 고유성 처리](snapstart-uniqueness.md)
+ [Lambda 함수 스냅샷 전후 코드 구현](snapstart-runtime-hooks.md)
+ [Lambda SnapStart 모니터링](snapstart-monitoring.md)
+ [Lambda SnapStart의 보안 모델](snapstart-security.md)
+ [Lambda SnapStart 성능 극대화](snapstart-best-practices.md)
+ [Lambda 함수에 대한 SnapStart 오류 문제 해결](snapstart-troubleshooting.md)

## SnapStart를 사용하는 경우
<a name="snapstart-use-cases"></a>

Lambda SnapStart는 로드 모듈 종속성 또는 프레임워크와 같은 일회성 초기화 코드로 인해 발생하는 지연 시간 변동성을 해결하도록 설계되었습니다. 이러한 작업은 초기 간접 호출 중에 완료하는 데 몇 초 정도 걸릴 수 있습니다. SnapStart를 사용하여 최적의 시나리오에서 이 지연 시간을 몇 초에서 1초 미만의 지연 시간으로 줄입니다. SnapStart는 대규모 함수 호출에서 사용할 때 가장 효과적입니다. 자주 간접 호출되지 않는 함수에서는 동일한 성능 향상이 이루어지지 않을 수 있습니다.

SnapStart는 특히 두 가지 기본 유형의 애플리케이션에 유용합니다.
+ **지연 시간에 민감한 API 및 사용자 흐름:** 중요한 API 엔드포인트 또는 사용자 대면 흐름의 일부인 함수는 SnapStart의 단축된 지연 시간 및 개선된 응답 시간의 이점을 누릴 수 있습니다.
+ **지연 시간에 민감한 데이터 처리 워크플로:** Lambda 함수를 사용하는 시간 제한 데이터 처리 워크플로에서는 이상치 함수 초기화 지연 시간을 줄여 처리량을 개선할 수 있습니다.

[프로비저닝된 동시성](provisioned-concurrency.md)을 통해 함수를 초기화하고 두 자릿수 밀리초 내로 응답할 수 있습니다. 애플리케이션에 SnapStart로 적절하게 해결할 수 없는 엄격한 콜드 스타트 지연 시간 요구 사항이 있는 경우 프로비저닝된 동시성을 사용합니다.

## 지원 기능 및 제한 사항
<a name="snapstart-runtimes"></a>

SnapStart는 다음과 같은 [Lambda 관리형 런타임](lambda-runtimes.md)에 대해 사용할 수 있습니다.
+ Java 11 이상
+ Python 3.12 이상
+ .NET 8 이상. [.NET에 대한 Lambda 주석 프레임워크](csharp-handler.md#csharp-handler-annotations)를 사용하는 경우 SnapStart와의 호환성을 보장하기 위해 [Amazon.Lambda.Annotations](https://www.nuget.org/packages/Amazon.Lambda.Annotations) 버전 1.6.0 이상으로 업그레이드합니다.

다른 관리형 런타임(예: `nodejs24.x` 및 `ruby3.4`), [OS 전용 런타임](runtimes-provided.md), [컨테이너 이미지](images-create.md)는 지원되지 않습니다.

SnapStart는 [프로비저닝된 동시성](provisioned-concurrency.md), [Amazon Elastic File System(Amazon EFS)](https://docs.aws.amazon.com/efs/latest/ug/accessing-fs.html) 또는 512MB보다 큰 임시 스토리지를 지원하지 않습니다.

**참고**  
[게시된 함수 버전](configuration-versions.md#configuration-versions-config) 및 버전을 가리키는 [별칭](configuration-aliases.md)에서만 SnapStart를 사용할 수 있습니다. 게시되지 않은 함수 버전(\$1LATEST)에서는 SnapStart를 사용할 수 없습니다.

## 지원되는 리전
<a name="snapstart-supported-regions"></a>

Lambda SnapStart는 아시아 태평양(뉴질랜드) 및 아시아 태평양(타이베이)을 제외한 모든 [상용 리전](https://docs.aws.amazon.com/general/latest/gr/glos-chap.html#region)에서 사용할 수 있습니다.

## 호환성 고려 사항
<a name="snapstart-compatibility"></a>

SnapStart를 사용하면 Lambda가 단일 스냅샷을 여러 실행 환경의 초기 상태로 사용합니다. [초기화 단계](lambda-runtime-environment.md#runtimes-lifecycle-ib)에서 함수가 다음을 사용하는 경우 SnapStart를 사용하기 전에 몇 가지 사항을 변경해야 할 수 있습니다.

**Uniqueness**  
초기화 코드가 스냅샷에 포함된 고유한 콘텐츠를 생성하는 경우, 해당 콘텐츠가 여러 실행 환경에서 재사용될 때 콘텐츠가 고유하지 않게 될 수 있습니다. SnapStart를 사용할 때 고유성을 유지하려면 초기화 후에 고유한 컨텐츠를 생성해야 합니다. 여기에는 유사 무작위성을 생성하는 데 사용되는 고유 ID, 고유 보안 암호 및 엔트로피가 포함됩니다. 고유성을 복원하는 방법은 [Lambda SnapStart를 사용한 고유성 처리](snapstart-uniqueness.md) 섹션을 참조하세요.

**네트워크 연결**  
Lambda가 스냅샷에서 함수를 재개할 때, 초기화 단계에서 함수가 설정한 연결 상태는 보장되지 않습니다. 네트워크 연결 상태를 확인하고 필요에 따라 다시 설정하세요. 대부분의 경우 AWS SDK가 설정한 네트워크 연결이 자동으로 재개됩니다. 다른 연결에 대해서는 [모범 사례](snapstart-best-practices.md)를 참조하세요.

**임시 데이터**  
일부 함수는 초기화 단계에서 임시 보안 인증 정보나 캐싱된 타임스탬프 같은 임시 데이터를 다운로드하거나 초기화합니다. SnapStart를 사용하지 않는 경우에도 임시 데이터를 사용하기 전에 함수 핸들러에서 해당 데이터를 새로 고치세요.

## SnapStart 요금
<a name="snapstart-pricing"></a>

**참고**  
Java 관리형 런타임의 경우 SnapStart에 대한 추가 비용이 없습니다. 함수에 대한 요청 수, 코드를 실행하는 데 걸리는 시간, 함수에 대해 구성된 메모리를 기준으로 요금이 청구됩니다.

SnapStart 사용 비용에는 다음이 포함됩니다.
+ **캐싱:** SnapStart를 활성화한 상태로 게시하는 모든 함수 버전에 대해 스냅샷 캐싱 및 유지 관리 비용을 지불합니다. 요금은 함수에 할당하는 [메모리](configuration-memory.md) 양에 따라 달라집니다. 최소 3시간의 요금이 부과됩니다. 함수가 [활성](snapstart-activate.md#snapstart-active) 상태로 유지되는 한 계속 요금이 청구됩니다. [ListVersionsByFunction](https://docs.aws.amazon.com/lambda/latest/api/API_ListVersionsByFunction.html) API 작업을 사용하여 함수 버전을 식별한 다음, [DeleteFunction](https://docs.aws.amazon.com/lambda/latest/api/API_DeleteFunction.html)을 사용하여 미사용 버전을 삭제합니다. 미사용 함수 버전을 자동으로 삭제하려면 Serverless Land의 [Lambda Version Cleanup](https://serverlessland.com/workflows/step-functions-lambda-version-cleanup) 패턴을 참조하세요.
+ **복원:** 함수 인스턴스가 스냅샷에서 복원될 때마다 복원 요금을 지불합니다. 요금은 함수에 할당하는 메모리 양에 따라 달라집니다.

모든 Lambda 함수와 마찬가지로 함수 핸들러에서 실행하는 코드에는 지속 시간 요금이 적용됩니다. SnapStart 함수의 경우 지속 시간 요금은 핸들러 외부에서 선언된 초기화 코드, 런타임에서 로드하는 데 걸리는 시간, [런타임 후크](snapstart-runtime-hooks.md)에서 실행하는 모든 코드에 적용됩니다. 지속 시간은 코드 실행을 시작한 시점부터 코드가 반환되거나 종료될 때까지 계산되며 가장 가까운 1ms 단위로 반올림합니다. Lambda는 복원력을 위해 스냅샷의 캐시된 사본을 유지 관리하고 런타임 업그레이드 및 해당 보안 패치와 같은 소프트웨어 업데이트를 자동으로 적용합니다. Lambda가 소프트웨어 업데이트를 적용하기 위해 초기화 코드를 다시 실행할 때마다 요금이 부과됩니다.

SnapStart 사용 비용에 대한 자세한 내용은 [AWS Lambda 요금](https://aws.amazon.com/lambda/pricing/#SnapStart_Pricing)을 참조하세요.

# Lambda SnapStart 활성화 및 관리
<a name="snapstart-activate"></a>

SnapStart를 사용하려면 새 Lambda 함수 또는 기존 Lambda 함수에 대해 SnapStart를 활성화해야 합니다. 그런 다음 함수 버전을 게시하고 간접 호출합니다.

**Topics**
+ [SnapStart 활성화(콘솔)](#snapshot-console)
+ [SnapStart 활성화(AWS CLI)](#snapshot-cli)
+ [SnapStart 활성화(API)](#snapshot-api)
+ [Lambda SnapStart와 함수 상태](#snapstart-function-states)
+ [스냅샷 업데이트](#update-snapshot)
+ [AWS SDK를 통해 SnapStart 사용](#snapstart-credentials)
+ [CloudFormation, AWS SAM 및 AWS CDK에 SnapStart 사용](#snapstart-cfn-sam)
+ [스냅샷 삭제](#snapshot-delete)

## SnapStart 활성화(콘솔)
<a name="snapshot-console"></a>

**함수에 대해 SnapStart를 활성화하려면**

1. Lambda 콘솔의 [함수 페이지](https://console.aws.amazon.com/lambda/home#/functions)를 엽니다.

1. 함수의 이름을 선택합니다.

1. **Configuration**(구성)을 선택한 다음 **General configuration**(일반 구성)을 선택합니다.

1. **General configuration**(일반 구성) 창에서 **Edit**(편집)를 선택합니다.

1. **Edit basic settings**(기본 설정 편집) 페이지의 **SnapStart**에서 **Published versions**(게시된 버전)을 선택합니다.

1. **저장**을 선택합니다.

1. [함수 버전을 게시합니다](configuration-versions.md#configuration-versions-config). Lambda는 코드를 초기화하고, 초기화된 실행 환경의 스냅샷을 생성한 다음, 액세스 지연 시간이 짧아지도록 스냅샷을 캐싱합니다.

1. [함수 버전을 간접 호출합니다](configuration-versions.md#versioning-versions-using).

## SnapStart 활성화(AWS CLI)
<a name="snapshot-cli"></a>

**기존 함수에 대해 SnapStart를 활성화하려면**

1. **--snap-start** 옵션과 함께 [update-function-configuration](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-configuration.html) 명령을 실행하여 함수 구성을 업데이트합니다.

   ```
   aws lambda update-function-configuration \
     --function-name my-function \
     --snap-start ApplyOn=PublishedVersions
   ```

1. [publish-version](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/publish-version.html) 명령을 사용하여 함수 버전을 게시합니다.

   ```
   aws lambda publish-version \
     --function-name my-function
   ```

1. [get-function-configuration](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/get-function-configuration.html) 명령을 실행하고 버전 번호를 지정하여 해당 함수 버전에 대해 SnapStart가 활성화되었는지 확인합니다. 다음은 버전 1을 지정하는 예입니다.

   ```
   aws lambda get-function-configuration \
     --function-name my-function:1
   ```

   응답에 [OptimizationStatus](https://docs.aws.amazon.com/lambda/latest/api/API_SnapStartResponse.html)가 `On`으로, [State](https://docs.aws.amazon.com/lambda/latest/api/API_GetFunctionConfiguration.html#lambda-GetFunctionConfiguration-response-State)가 `Active`로 표시되는 경우, SnapStart가 활성화되어 있는 것이며 지정된 함수 버전에 대한 스냅샷을 사용할 수 있습니다.

   ```
   "SnapStart": { 
       "ApplyOn": "PublishedVersions",
       "OptimizationStatus": "On"
    },
    "State": "Active",
   ```

1. [간접 호출](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/invoke.html) 명령을 실행하고 버전을 지정하여 함수 버전을 간접 호출합니다. 다음은 버전 1을 간접 호출하는 예입니다.

   ```
   aws lambda invoke \
     --cli-binary-format raw-in-base64-out \
     --function-name my-function:1 \
     --payload '{ "name": "Bob" }' \
     response.json
   ```

   **cli-binary-format** 옵션은 AWS CLI 버전 2를 사용할 때 필요합니다. 이 설정을 기본 설정으로 지정하려면 `aws configure set cli-binary-format raw-in-base64-out`을(를) 실행하세요. 자세한 내용은 [AWS CLI 지원되는 글로벌 명령줄 옵션](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list)을 AWS Command Line Interface 사용 설명서 버전 2에서 참조하세요.

**새 함수를 생성할 때 SnapStart를 활성화하려면**

1. **--snap-start** 옵션과 함께 [create-function](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/create-function.html) 명령을 실행하여 함수를 생성합니다. **--role**에 [실행 역할](lambda-intro-execution-role.md)의 Amazon 리소스 이름(ARN)을 지정합니다.

   ```
   aws lambda create-function \
     --function-name my-function \
     --runtime "java25" \
     --zip-file fileb://my-function.zip \
     --handler my-function.handler \
     --role arn:aws:iam::111122223333:role/lambda-ex \
     --snap-start ApplyOn=PublishedVersions
   ```

1. [publish-version](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/publish-version.html) 명령을 사용하여 버전을 생성합니다.

   ```
   aws lambda publish-version \
     --function-name my-function
   ```

1. [get-function-configuration](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/get-function-configuration.html) 명령을 실행하고 버전 번호를 지정하여 해당 함수 버전에 대해 SnapStart가 활성화되었는지 확인합니다. 다음은 버전 1을 지정하는 예입니다.

   ```
   aws lambda get-function-configuration \
     --function-name my-function:1
   ```

   응답에 [OptimizationStatus](https://docs.aws.amazon.com/lambda/latest/api/API_SnapStartResponse.html)가 `On`으로, [State](https://docs.aws.amazon.com/lambda/latest/api/API_GetFunctionConfiguration.html#lambda-GetFunctionConfiguration-response-State)가 `Active`로 표시되는 경우, SnapStart가 활성화되어 있는 것이며 지정된 함수 버전에 대한 스냅샷을 사용할 수 있습니다.

   ```
   "SnapStart": { 
        "ApplyOn": "PublishedVersions",
        "OptimizationStatus": "On"
     },
     "State": "Active",
   ```

1. [간접 호출](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/invoke.html) 명령을 실행하고 버전을 지정하여 함수 버전을 간접 호출합니다. 다음은 버전 1을 간접 호출하는 예입니다.

   ```
   aws lambda invoke \
     --cli-binary-format raw-in-base64-out \
     --function-name my-function:1 \
     --payload '{ "name": "Bob" }' \
     response.json
   ```

   **cli-binary-format** 옵션은 AWS CLI 버전 2를 사용할 때 필요합니다. 이 설정을 기본 설정으로 지정하려면 `aws configure set cli-binary-format raw-in-base64-out`을(를) 실행하세요. 자세한 내용은 [AWS CLI 지원되는 글로벌 명령줄 옵션](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list)을 AWS Command Line Interface 사용 설명서 버전 2에서 참조하세요.

## SnapStart 활성화(API)
<a name="snapshot-api"></a>

**SnapStart를 활성화하려면**

1. 다음 중 하나를 수행하세요.
   + [CreateFunction](https://docs.aws.amazon.com/lambda/latest/api/API_CreateFunction.html) API 작업을 [SnapStart](https://docs.aws.amazon.com/lambda/latest/api/API_SnapStart.html) 파라미터와 함께 사용하여 SnapStart가 활성화된 상탤 새 함수를 생성합니다.
   + [UpdateFunctionConfiguration](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateFunctionConfiguration.html) 작업을 [SnapStart](https://docs.aws.amazon.com/lambda/latest/api/API_SnapStart.html) 파라미터와 함께 사용하여 기존 함수에 대해 SnapStart를 활성화합니다.

1. [PublishVersion](https://docs.aws.amazon.com/lambda/latest/api/API_PublishVersion.html) 작업을 사용하여 함수 버전을 게시합니다. Lambda는 코드를 초기화하고, 초기화된 실행 환경의 스냅샷을 생성한 다음, 액세스 지연 시간이 짧아지도록 스냅샷을 캐싱합니다.

1. [GetFunctionConfiguration](https://docs.aws.amazon.com/lambda/latest/api/API_GetFunctionConfiguration.html) 작업을 사용하여 해당 함수 버전에 대해 SnapStart가 활성화되어 있는지 확인합니다. 버전 번호를 지정하여 해당 버전에 SnapStart가 활성화되어 있는지 확인합니다. 응답에 [OptimizationStatus](https://docs.aws.amazon.com/lambda/latest/api/API_SnapStartResponse.html)가 `On`으로, [State](https://docs.aws.amazon.com/lambda/latest/api/API_GetFunctionConfiguration.html#lambda-GetFunctionConfiguration-response-State)가 `Active`로 표시되는 경우, SnapStart가 활성화되어 있는 것이며 지정된 함수 버전에 대한 스냅샷을 사용할 수 있습니다.

   ```
   "SnapStart": { 
           "ApplyOn": "PublishedVersions",
           "OptimizationStatus": "On"
        },
        "State": "Active",
   ```

1. [간접 호출](https://docs.aws.amazon.com/lambda/latest/api/API_Invoke.html) 작업을 사용하여 함수 버전을 간접 호출합니다.

## Lambda SnapStart와 함수 상태
<a name="snapstart-function-states"></a>

SnapStart를 사용할 때 다음과 같은 함수 상태가 발생할 수 있습니다.

**보류 중**  
Lambda에서 코드를 초기화하고 초기화된 실행 환경의 스냅샷을 생성하고 있습니다. 해당 함수 버전에서 작동하는 호출 또는 기타 API 작업은 실패합니다.

**활성**  
스냅샷 생성이 완료되었으며, 함수를 간접 호출할 수 있습니다. SnapStart를 사용하려면 게시되지 않은 버전(\$1LATEST)이 아니라 게시된 함수 버전을 간접 호출해야 합니다.

**비활성**  
Lambda가 함수 스냅샷을 주기적으로 재생성하여 소프트웨어 업데이트를 적용할 때 `Inactive` 상태가 발생할 수 있습니다. 이 경우 함수 초기화에 실패할 경우 함수가 `Inactive` 상태에 들어갈 수 있습니다.  
Java 런타임을 사용하는 기능의 경우, Lambda에서 간접 호출 없이 14일 후에 스냅샷을 삭제합니다. 14일이 지난 후에 함수 버전을 호출하면 Lambda는 `SnapStartNotReadyException` 응답을 반환하고 새 스냅샷을 초기화하기 시작합니다. 함수 버전이 `Active` 상태에 도달할 때까지 기다린 후 다시 간접 호출하세요.

**Failed**  
초기화 코드를 실행하거나 스냅샷을 생성하는 경우 Lambda에서 오류가 발생했습니다.

## 스냅샷 업데이트
<a name="update-snapshot"></a>

Lambda는 게시된 각 함수 버전마다 스냅샷을 생성합니다. 스냅샷을 업데이트하려면 새 함수 버전을 게시합니다.

## AWS SDK를 통해 SnapStart 사용
<a name="snapstart-credentials"></a>

함수에서 AWS SDK를 호출하기 위해 Lambda는 함수의 실행 역할을 가정하여 휘발성 자격 증명 세트를 생성합니다. 이러한 보안 인증 정보는 함수를 호출할 때 환경 변수로 사용할 수 있습니다. 코드에서 직접 SDK의 보안 인증 정보를 제공할 필요가 없습니다. 기본적으로 보안 인증 공급자 체인은 사용자가 보안 인증 정보를 설정할 수 있는 각 위치를 순차적으로 확인하고, 일반적으로 환경 변수(`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY` 및 `AWS_SESSION_TOKEN`)인 사용 가능한 첫 번째 위치를 선택합니다.

**참고**  
SnapStart가 활성화되면 Lambda 런타임은 자동으로 액세스 키 환경 변수 대신 컨테이너 자격 증명(`AWS_CONTAINER_CREDENTIALS_FULL_URI` 및 `AWS_CONTAINER_AUTHORIZATION_TOKEN`)을 사용합니다. 따라서 함수가 복원되기 전에 보안 인증 정보가 만료되지 않습니다.

## CloudFormation, AWS SAM 및 AWS CDK에 SnapStart 사용
<a name="snapstart-cfn-sam"></a>
+ **AWS CloudFormation:** 템플릿에서 [SnapStart](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lambda-function-snapstart.html) 엔터티를 선언합니다.
+ **AWS Serverless Application Model(AWS SAM):** 템플릿에서 [SnapStart](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html#sam-function-snapstart) 속성을 선언합니다.
+ **AWS Cloud Development Kit (AWS CDK):** [SnapStartProperty](https://docs.aws.amazon.com/cdk/api/v2/java/software/amazon/awscdk/services/lambda/CfnFunction.SnapStartProperty.html) 유형을 사용합니다.

## 스냅샷 삭제
<a name="snapshot-delete"></a>

Lambda는 다음 경우에 스냅샷을 삭제합니다.
+ 함수 또는 함수 버전을 삭제한 경우.
+ **Java 런타임만 해당** - 14일 동안 함수 버전을 간접 호출하지 않습니다. 호출 없이 14일이 지나면 함수 버전이 [비활성](#snapstart-function-states) 상태로 전환됩니다. 14일이 지난 후에 함수 버전을 간접 호출하면 Lambda는 `SnapStartNotReadyException` 응답을 반환하고 새 스냅샷을 초기화하기 시작합니다. 함수 버전이 [활성](#snapstart-function-states) 상태에 도달할 때까지 기다린 후 다시 간접 호출하세요.

Lambda는 일반 데이터 보호 규정(GDPR)에 따라, 삭제된 스냅샷에 연결된 모든 리소스를 제거합니다.

# Lambda SnapStart를 사용한 고유성 처리
<a name="snapstart-uniqueness"></a>

SnapStart 함수에서 호출이 스케일 업되면 Lambda는 초기화된 단일 스냅샷을 사용하여 여러 실행 환경을 재개합니다. 초기화 코드가 스냅샷에 포함된 고유한 콘텐츠를 생성하는 경우, 해당 콘텐츠가 여러 실행 환경에서 재사용될 때 콘텐츠가 고유하지 않게 될 수 있습니다. SnapStart를 사용할 때 고유성을 유지하려면 초기화 후에 고유한 컨텐츠를 생성해야 합니다. 여기에는 유사 무작위성을 생성하는 데 사용되는 고유 ID, 고유 보안 암호 및 엔트로피가 포함됩니다.

코드에서 고유성을 유지하려면 다음 모범 사례를 따르는 것이 좋습니다. 또한 Java 함수와 관련해 Lambda는 고유성을 가정한 코드를 검사할 수 있도록 오픈 소스 [SnapStart 검사 도구](#snapstart-scanning)를 제공합니다. 초기화 단계에서 고유한 데이터를 생성하는 경우 [런타임 후크](snapstart-runtime-hooks.md)를 사용하여 고유성을 복원할 수 있습니다. 런타임 후크를 사용하면 Lambda가 스냅샷을 생성하기 직전이나 Lambda가 스냅샷에서 함수를 재개한 직후에 특정 코드를 실행할 수 있습니다.

## 초기화 중에 고유성에 의존하는 상태를 저장하지 마세요.
<a name="snapstart-caching-unique"></a>

함수의 [초기화 단계](lambda-runtime-environment.md#runtimes-lifecycle-ib)에서는 무작위 함수에 대한 시드 설정 또는 로깅을 위한 고유 ID를 생성하는 경우와 같이 고유하도록 의도된 데이터를 캐싱하지 마세요. 대신 함수 핸들러 내에서 무작위 함수를 위해 고유한 데이터를 생성하거나 시드를 설정하거나 [런타임 후크](snapstart-runtime-hooks.md)를 사용하는 것이 좋습니다.

다음 예제에서는 함수 핸들러에서 UUID를 생성하는 방법을 보여줍니다.

------
#### [ Java ]

**Example - 함수 핸들러에서 고유 ID 생성**  

```
import java.util.UUID;
  public class Handler implements RequestHandler<String, String> {
    private static UUID uniqueSandboxId = null;
    @Override
    public String handleRequest(String event, Context context) {
      if (uniqueSandboxId == null)
        uniqueSandboxId = UUID.randomUUID();
      System.out.println("Unique Sandbox Id: " + uniqueSandboxId);
      return "Hello, World!";
    }
  }
```

------
#### [ Python ]

**Example - 함수 핸들러에서 고유 ID 생성**  

```
import json
import random
import time

unique_number = None

def lambda_handler(event, context):
    seed = int(time.time() * 1000) 
    random.seed(seed)
    global unique_number
    if not unique_number:
        unique_number = random.randint(1, 10000)
        
    print("Unique number: ", unique_number)
    
    return "Hello, World!"
```

------
#### [ .NET ]

**Example - 함수 핸들러에서 고유 ID 생성**  

```
namespace Example;
public class SnapstartExample
{
    private Guid _myExecutionEnvironmentGuid;
    public SnapstartExample()
    {
        // This GUID is set for non-restore use cases, such as testing or if SnapStart is turned off
        _myExecutionEnvironmentGuid = new Guid();
        // Register the method which will run after each restore. You may need to update Amazon.Lambda.Core to see this
        Amazon.Lambda.Core.SnapshotRestore.RegisterAfterRestore(MyAfterRestore);
    }

    private ValueTask MyAfterRestore()
    {
        // After restoring this snapshot to a new execution environment, update the GUID
        _myExecutionEnvironmentGuid = new Guid();
        return ValueTask.CompletedTask;
    }

    public string Handler()
    {
        return $"Hello World! My Execution Environment GUID is {_myExecutionEnvironmentGuid}";
    }
}
```

------

## 암호학적으로 안전한 가상 난수 생성기(CSPRNG) 사용
<a name="snapstart-csprng"></a>

애플리케이션이 무작위성에 의존하는 경우 암호학적으로 안전한 난수 생성기(CSPRNG)를 사용하는 것이 좋습니다. OpenSSL 1.0.2 외에도 Lambda 관리형 런타임에는 다음과 같은 기본 제공 CSPRNG가 포함됩니다.
+ **Java:** `java.security.SecureRandom`
+ **Python:** `random.SystemRandom`
+ **.NET:** `System.Security.Cryptography.RandomNumberGenerator`

항상 `/dev/random` 또는 `/dev/urandom`에서 난수를 가져오는 소프트웨어는 SnapStart를 사용하여 무작위성도 유지합니다.

AWS 암호화 라이브러리는 다음 표에 지정된 최소 버전부터, SnapStart를 사용하여 자동으로 무작위성을 유지합니다. Lambda 함수와 함께 이러한 라이브러리를 사용하는 경우, 다음 최소 버전 이상을 사용해야 합니다.


****  

| 라이브러리 | 지원되는 최소 버전(x86) | 지원되는 최소 버전(ARM) | 
| --- | --- | --- | 
| AWS libcrypto (AWS-LC) |  1.16.0  |  1.30.0  | 
| AWS libcrypto FIPS |  2.0.13  | 2.0.13 | 

다음의 라이브러리를 통해 전이적 종속성으로 Lambda 함수와 함께 앞의 암호화 라이브러리를 패키징하는 경우, 다음 최소 버전 이상을 사용해야 합니다.


****  

| 라이브러리 | 지원되는 최소 버전(x86) | 지원되는 최소 버전(ARM) | 
| --- | --- | --- | 
| AWS SDK for Java 2.x |  2.23.20  |  2.26.12  | 
| AWS Common Runtime for Java |  0.29.8  |  0.29.25  | 
| Amazon Corretto Crypto Provider |  2.4.1  | 2.4.1 | 
| Amazon Corretto Crypto Provider FIPS |  2.4.1  | 2.4.1 | 

다음 예제에서는 함수가 스냅샷에서 함수를 복원하는 경우에도 CSPRNG를 사용하여 고유한 번호 시퀀스를 보장하는 방법을 보여줍니다.

------
#### [ Java ]

**Example – java.security.SecureRandom**  

```
import java.security.SecureRandom;
  public class Handler implements RequestHandler<String, String> {
    private static SecureRandom rng = new SecureRandom();
    @Override
    public String handleRequest(String event, Context context) {
      for (int i = 0; i < 10; i++) {
        System.out.println(rng.next());
      }
      return "Hello, World!";
    }
  }
```

------
#### [ Python ]

**Example – random.SystemRandom**  

```
import json
import random

secure_rng = random.SystemRandom()

def lambda_handler(event, context):
    random_numbers = [secure_rng.random() for _ in range(10)]
    
    for number in random_numbers:
        print(number)
    
    return "Hello, World!"
```

------
#### [ .NET ]

**Example – RandomNumberGenerator**  

```
using Amazon.Lambda.Core;
using System.Security.Cryptography;
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace DotnetSecureRandom;

public class Function
{
    public string FunctionHandler()
    {
        using (RandomNumberGenerator rng = RandomNumberGenerator.Create())
        {
            byte[] randomUnsignedInteger32Bytes = new byte[4];
            for (int i = 0; i < 10; i++)
            {
                rng.GetBytes(randomUnsignedInteger32Bytes);
                int randomInt32 = BitConverter.ToInt32(randomUnsignedInteger32Bytes, 0);
                Console.WriteLine("{0:G}", randomInt32);
            }
        }
        return "Hello World!";
    }
}
```

------

## SnapStart 스캔 도구(Java만 해당)
<a name="snapstart-scanning"></a>

Lambda에서는 고유성을 가정하는 코드를 검사할 수 있도록 Java에 대한 검사 도구를 제공합니다. SnapStart 검사 도구는 일련의 규칙에 대해 정적 분석을 실행하는 오픈 소스 [SpotBugs](https://spotbugs.github.io/) 플러그인입니다. 이 검사 도구는 고유성과 관련한 가정에 위배될 수 있는 잠재적인 코드 구현을 식별하는 데 도움이 됩니다. 설치 지침과 검사 도구가 수행하는 검사 목록은 GitHub에서 [aws-lambda-snapstart-java-rules](https://github.com/aws/aws-lambda-snapstart-java-rules) 리포지토리를 참조하세요.

SnapStart를 사용하여 고유성을 처리하는 방법에 대해 자세한 내용은 AWS 컴퓨팅 블로그에서 [AWS Lambda SnapStart를 사용하여 더 빠르게 시작하기](https://aws.amazon.com/blogs/compute/starting-up-faster-with-aws-lambda-snapstart/)를 참조하세요.

# Lambda 함수 스냅샷 전후 코드 구현
<a name="snapstart-runtime-hooks"></a>

Lambda가 스냅샷을 생성하기 전이나 Lambda가 스냅샷에서 함수를 재개한 후에 런타임 후크를 사용하여 코드를 구현할 수 있습니다. 런타임 후크는 다음과 같은 다양한 목적으로 유용합니다.
+ **정리 및 초기화:** 스냅샷을 생성하기 전에 런타임 후크를 사용하여 정리 또는 리소스 해제 작업을 수행할 수 있습니다. 스냅샷이 복원된 후 런타임 후크를 사용하여 스냅샷에 캡처되지 않은 리소스 또는 상태를 다시 초기화할 수 있습니다.
+ **동적 구성:** 스냅샷을 생성하기 전 또는 복원한 후에 런타임 후크를 사용하여 구성 또는 기타 메타데이터를 동적으로 업데이트할 수 있습니다. 함수가 런타임 환경의 변경 사항에 맞게 적응해야 하는 경우에 유용할 수 있습니다.
+ **외부 통합:** 런타임 후크를 사용하여 체크포인트 및 복원 프로세스의 일부로 알림 전송 또는 외부 상태 업데이트와 같은 외부 서비스 또는 시스템과 통합할 수 있습니다.
+ **성능 조정:** 런타임 후크를 사용하여 종속 항목을 미리 로드하는 등 함수의 시작 시퀀스를 미세 조정할 수 있습니다. 자세한 내용은 [성능 튜닝](snapstart-best-practices.md#snapstart-tuning) 단원을 참조하십시오.

다음 페이지에서는 원하는 런타임에 대해 런타임 후크를 구현하는 방법을 설명합니다.

**Topics**
+ [Java](snapstart-runtime-hooks-java.md)
+ [Python](snapstart-runtime-hooks-python.md)
+ [.NET](snapstart-runtime-hooks-dotnet.md)

# Java에 대한 Lambda SnapStart 런타임 후크
<a name="snapstart-runtime-hooks-java"></a>

Lambda가 스냅샷을 생성하기 전이나 Lambda가 스냅샷에서 함수를 재개한 후에 런타임 후크를 사용하여 코드를 구현할 수 있습니다. 런타임 후크는 오픈 소스 체크포인트 Coordinated Restore at Checkpoint(CRaC) 프로젝트의 일부로 제공됩니다. [Open Java Development Kit(OpenJDK)](https://wiki.openjdk.org/display/crac)용 CRaC는 개발 중입니다. 참조 애플리케이션에 CRaC를 사용하는 방법의 예는 GitHub에서 [CRaC](https://github.com/CRaC/docs/blob/master/STEP-BY-STEP.md) 리포지토리를 참조하세요. CRaC는 세 가지 주요 요소를 사용합니다.
+ `Resource` - `beforeCheckpoint()`와 `afterRestore()`라는 두 가지 메서드가 있는 인터페이스입니다. 이러한 메서드를 사용하여 스냅샷 생성 전과 복원 후에 실행할 코드를 구현합니다.
+ `Context <R extends Resource>` - 체크포인트 및 복원에 대한 알림을 받으려면 `Resource`를 `Context`에 등록해야 합니다.
+ `Core` - 정적 메서드 `Core.getGlobalContext()`를 통해 기본 글로벌 `Context`를 제공하는 조정 서비스입니다.

`Context` 및 `Resource`에 대한 자세한 내용은 CRaC 설명서에서 [org.crac 패키징](https://javadoc.io/doc/io.github.crac/org-crac/latest/index.html)을 참조하세요.

다음 단계에 따라 [org.crac 패키지](https://github.com/CRaC/org.crac)를 사용하여 런타임 후크를 구현합니다. Lambda 런타임에는 체크포인트를 생성하기 전과 복원 후에 런타임 후크를 호출하는 사용자 지정 CRaC 컨텍스트 구현이 포함되어 있습니다.

## 런타임 후크 등록 및 실행
<a name="runtime-hooks-registration-java"></a>

Lambda에서 런타임 후크를 실행하는 순서는 등록 순서에 따라 결정됩니다. 등록 순서는 코드의 가져오기, 정의 또는 실행 순서를 따릅니다.
+ `beforeCheckpoint()`: 등록의 역순으로 실행됨
+ `afterRestore()`: 등록 순서대로 실행됨

등록된 모든 후크를 올바르게 가져와서 함수 코드에 포함했는지 확인합니다. 별도의 파일 또는 모듈에 런타임 후크를 등록하는 경우 모듈을 함수의 핸들러 파일에 직접 가져오거나 더 큰 패키지의 일부로 가져와야 합니다. 함수 핸들러에 파일 또는 모듈을 가져오지 않으면 Lambda는 런타임 후크를 무시합니다.

**참고**  
Lambda가 스냅샷을 생성할 때 초기화 코드를 최대 15분 동안 실행할 수 있습니다. 시간 제한은 130초 또는 [구성된 함수 제한 시간](configuration-timeout.md)(최대 900초) 중 더 높은 값입니다. `beforeCheckpoint()` 런타임 후크는 초기화 코드 시간 제한에 포함됩니다. Lambda에서 스냅샷을 복원하는 경우 런타임이 로드되고 `afterRestore()` 런타임 후크가 제한 시간(10초) 내에 완료되어야 합니다. 그렇지 않으면 SnapStartTimeoutException이 발생합니다.

## 1단계: 빌드 구성 업데이트
<a name="runtime-hooks-java-update-build"></a>

빌드 구성에 `org.crac` 종속성을 추가합니다. 다음 예에서는 Gradle을 사용합니다. 다른 빌드 시스템의 예제는 [Apache Maven 설명서](https://search.maven.org/artifact/io.github.crac/org-crac/0.1.3/jar)를 참조하세요.

```
dependencies {
    compile group: 'com.amazonaws', name: 'aws-lambda-java-core', version: '1.2.1'
    # All other project dependecies go here:
    # ...
    # Then, add the org.crac dependency:
 implementation group: 'org.crac', name: 'crac', version: '1.4.0'
}
```

## 2단계: Lambda 핸들러 업데이트
<a name="runtime-hooks-java-update-handler"></a>

Lambda 함수의 *핸들러*는 이벤트를 처리하는 함수 코드의 메서드입니다. 함수가 간접 호출되면 Lambda는 핸들러 메서드를 실행합니다. 함수는 핸들러가 응답을 반환하거나 종료하거나 제한 시간이 초과될 때까지 실행됩니다.

자세한 내용은 [Java에서 Lambda 함수 핸들러 정의](java-handler.md) 섹션을 참조하세요.

다음 예제 핸들러는 체크포인트 생성 전(`beforeCheckpoint()`)과 복원 후(`afterRestore()`)에 코드를 실행하는 방법을 보여줍니다. 또한 이 핸들러는 런타임 관리 글로벌 `Resource`에 `Context`를 등록합니다.

**참고**  
Lambda가 스냅샷을 생성할 때 초기화 코드를 최대 15분 동안 실행할 수 있습니다. 시간 제한은 130초 또는 [구성된 함수 제한 시간](configuration-timeout.md)(최대 900초) 중 더 높은 값입니다. `beforeCheckpoint()` 런타임 후크는 초기화 코드 시간 제한에 포함됩니다. Lambda가 스냅샷을 복원할 때, 런타임(JVM)이 로드되고 `afterRestore()` 런타임 후크가 제한 시간(10초) 내에 완료되어야 합니다. 그렇지 않으면 SnapStartTimeoutException이 발생합니다.

```
...
  import org.crac.Resource;
  import org.crac.Core;
  ... 
public class CRaCDemo implements RequestStreamHandler, Resource {
    public CRaCDemo() {
      Core.getGlobalContext().register(this);
    }
    public String handleRequest(String name, Context context) throws IOException {
      System.out.println("Handler execution");
      return "Hello " + name;
    }
    @Override
    public void beforeCheckpoint(org.crac.Context<? extends Resource> context)
        throws Exception {
      System.out.println("Before checkpoint");
    }
    @Override
    public void afterRestore(org.crac.Context<? extends Resource> context)
        throws Exception {
      System.out.println("After restore");
```

`Context`는 등록된 객체에 대해서만 [https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/ref/WeakReference.html](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/ref/WeakReference.html)를 유지합니다. [https://javadoc.io/static/io.github.crac/org-crac/0.1.3/org/crac/Resource.html](https://javadoc.io/static/io.github.crac/org-crac/0.1.3/org/crac/Resource.html)가 가비지 수집된 경우 런타임 후크가 실행되지 않습니다. 런타임 후크가 실행되도록 하려면 코드에서 `Resource`에 대한 강력한 참조를 유지해야 합니다.

다음은 피해야 할 두 가지 패턴의 예입니다.

**Example - 강력한 참조가 없는 객체**  

```
Core.getGlobalContext().register( new MyResource() );
```

**Example - 익명 클래스의 객체**  

```
Core.getGlobalContext().register( new Resource() {
   
   @Override
   public void afterRestore(Context<? extends Resource> context) throws Exception {
    // ...
   }
   
   @Override
   public void beforeCheckpoint(Context<? extends Resource> context) throws Exception {
    // ...
   }

} );
```

대신 강력한 참조를 유지하세요. 다음 예제에서 등록된 리소스는 가비지 수집되지 않았으며 런타임 후크가 일관되게 실행됩니다.

**Example - 강력한 참조가 있는 객체**  

```
Resource myResource = new MyResource(); // This reference must be maintained to prevent the registered resource from being garbage collected
Core.getGlobalContext().register( myResource );
```

# Python에 대한 Lambda SnapStart 런타임 후크
<a name="snapstart-runtime-hooks-python"></a>

Lambda가 스냅샷을 생성하기 전이나 Lambda가 스냅샷에서 함수를 재개한 후에 런타임 후크를 사용하여 코드를 구현할 수 있습니다. Python 런타임 후크는 Python 관리형 런타임에 포함된 오픈 소스 [Snapshot Restore for Python 라이브러리](https://pypi.org/project/snapshot-restore-py/)의 일부로 사용할 수 있습니다. 이 라이브러리에서는 런타임 후크를 정의하는 데 사용할 수 있는 두 가지 데코레이터를 제공합니다.
+ `@register_before_snapshot`: Lambda가 스냅샷을 생성하기 전에 실행할 함수의 경우.
+ `@register_after_restore`: Lambda가 스냅샷에서 함수를 재개하는 경우 실행할 함수의 경우.

또는 다음 방법을 사용하여 런타임 후크에 대한 직접 호출 가능 항목을 등록할 수 있습니다.
+ `register_before_snapshot(func, *args, **kwargs)`
+ `register_after_restore(func, *args, **kwargs)`

## 런타임 후크 등록 및 실행
<a name="runtime-hooks-registration-python"></a>

Lambda에서 런타임 후크를 실행하는 순서는 등록 순서에 따라 결정됩니다.
+ 스냅샷 이전: 등록의 역순으로 실행됨
+ 스냅샷 이후: 등록 순서대로 실행됨

런타임 후크 등록 순서는 후크를 정의하는 방법에 따라 달라집니다. 데코레이터(`@register_before_snapshot` 및 `@register_after_restore`)를 사용하는 경우 등록 순서는 코드의 가져오기, 정의 또는 실행 순서를 따릅니다. 등록 순서를 더 제어해야 하는 경우 데코레이터 대신 `register_before_snapshot()` 및 `register_after_restore()` 메서드를 사용합니다.

등록된 모든 후크를 올바르게 가져와서 함수 코드에 포함했는지 확인합니다. 별도의 파일 또는 모듈에 런타임 후크를 등록하는 경우 모듈을 함수의 핸들러 파일에 직접 가져오거나 더 큰 패키지의 일부로 가져와야 합니다. 함수 핸들러에 파일 또는 모듈을 가져오지 않으면 Lambda는 런타임 후크를 무시합니다.

**참고**  
Lambda가 스냅샷을 생성할 때 초기화 코드를 최대 15분 동안 실행할 수 있습니다. 시간 제한은 130초 또는 [구성된 함수 제한 시간](configuration-timeout.md)(최대 900초) 중 더 높은 값입니다. `@register_before_snapshot` 런타임 후크는 초기화 코드 시간 제한에 포함됩니다. Lambda에서 스냅샷을 복원하는 경우 런타임이 로드되고 `@register_after_restore` 런타임 후크가 제한 시간(10초) 내에 완료되어야 합니다. 그렇지 않으면 SnapStartTimeoutException이 발생합니다.

## 예제
<a name="runtime-hooks-python-code-sample"></a>

다음 예제 핸들러는 체크포인트 생성 전(`@register_before_snapshot`)과 복원 후(`@register_after_restore`)에 코드를 실행하는 방법을 보여줍니다.

```
from snapshot_restore_py import register_before_snapshot, register_after_restore

def lambda_handler(event, context):
    # Handler code

@register_before_snapshot
def before_checkpoint():
    # Logic to be executed before taking snapshots

@register_after_restore
def after_restore():
    # Logic to be executed after restore
```

추가 예제는 AWS GitHub 리포지토리의 [Snapshot Restore for Python](https://github.com/aws/snapshot-restore-py/tree/main/examples)을 참조하세요.

# .NET에 대한 Lambda SnapStart 런타임 후크
<a name="snapstart-runtime-hooks-dotnet"></a>

Lambda가 스냅샷을 생성하기 전이나 Lambda가 스냅샷에서 함수를 재개한 후에 런타임 후크를 사용하여 코드를 구현할 수 있습니다. .NET 런타임 후크는 [Amazon.Lambda.Core](https://www.nuget.org/packages/Amazon.Lambda.Core) 패키지(버전 2.5.0 이상)의 일부로 사용 가능합니다. 이 라이브러리에서는 런타임 후크를 정의하는 데 사용할 수 있는 두 가지 방법을 제공합니다.
+ `RegisterBeforeSnapshot()`: 스냅샷 생성 전에 실행할 코드
+ `RegisterAfterSnapshot()`: 스냅샷에서 함수를 재개한 후 실행할 코드

**참고**  
[.NET에 대한 Lambda 주석 프레임워크](csharp-handler.md#csharp-handler-annotations)를 사용하는 경우 SnapStart와의 호환성을 보장하기 위해 [Amazon.Lambda.Annotations](https://www.nuget.org/packages/Amazon.Lambda.Annotations) 버전 1.6.0 이상으로 업그레이드합니다.

## 런타임 후크 등록 및 실행
<a name="runtime-hooks-registration-dotnet"></a>

초기화 코드에 후크를 등록합니다. Lambda 함수의 [실행 모델](csharp-handler.md#csharp-handler-setup)에 따라 다음 지침을 고려합니다.
+ [실행 가능한 어셈블리 접근 방식](csharp-handler.md#csharp-executable-assembly-handlers)의 경우 `RunAsync`로 Lambda 부트스트랩을 시작하기 전에 후크를 등록합니다.
+ [클래스 라이브러리 접근 방식](csharp-handler.md#csharp-class-library-handlers)의 경우 핸들러 클래스 생성자에 후크를 등록합니다.
+ [ASP.NET Core 애플리케이션](csharp-package-asp.md)의 경우 `WebApplications.Run` 메서드를 직접 호출하기 전에 후크를 등록합니다.

.NET에서 SnapStart에 대한 런타임 후크를 등록하려면 다음 방법을 사용합니다.

```
Amazon.Lambda.Core.SnapshotRestore.RegisterBeforeSnapshot(BeforeCheckpoint);
Amazon.Lambda.Core.SnapshotRestore.RegisterAfterRestore(AfterCheckpoint);
```

여러 후크 유형이 등록되면 Lambda에서 런타임 후크를 실행하는 순서는 등록 순서에 따라 결정됩니다.
+ `RegisterBeforeSnapshot()`: 등록의 역순으로 실행됨
+ `RegisterAfterSnapshot()`: 등록 순서대로 실행됨

**참고**  
Lambda가 스냅샷을 생성할 때 초기화 코드를 최대 15분 동안 실행할 수 있습니다. 시간 제한은 130초 또는 [구성된 함수 제한 시간](configuration-timeout.md)(최대 900초) 중 더 높은 값입니다. `RegisterBeforeSnapshot()` 런타임 후크는 초기화 코드 시간 제한에 포함됩니다. Lambda에서 스냅샷을 복원하는 경우 런타임이 로드되고 `RegisterAfterSnapshot()` 런타임 후크가 제한 시간(10초) 내에 완료되어야 합니다. 그렇지 않으면 SnapStartTimeoutException이 발생합니다.

## 예제
<a name="runtime-hooks-dotnet-code-sample"></a>

다음 함수 예제에서는 체크포인트 생성 전(`RegisterBeforeSnapshot`)과 복원 후(`RegisterAfterRestore`)에 코드를 실행하는 방법을 보여줍니다.

```
public class SampleClass
{
    public SampleClass()
    {
        Amazon.Lambda.Core.SnapshotRestore.RegisterBeforeSnapshot(BeforeCheckpoint);
        Amazon.Lambda.Core.SnapshotRestore.RegisterAfterRestore(AfterCheckpoint);
    }

    private ValueTask BeforeCheckpoint()
    {
        // Add logic to be executed before taking the snapshot
        return ValueTask.CompletedTask;
    }

    private ValueTask AfterCheckpoint()
    {
        // Add logic to be executed after restoring the snapshot
        return ValueTask.CompletedTask;
    }

    public APIGatewayProxyResponse FunctionHandler(APIGatewayProxyRequest request, ILambdaContext context)
    {
        // Add business logic

        return new APIGatewayProxyResponse
        {
            StatusCode = 200
        };
    }
}
```

# Lambda SnapStart 모니터링
<a name="snapstart-monitoring"></a>

Amazon CloudWatch, AWS X-Ray 및 [텔레메트리 API를 사용하여 확장의 실시간 텔레메트리 데이터에 액세스](telemetry-api.md)를 사용하여 Lambda SnapStart 함수를 모니터링할 수 있습니다.

**참고**  
`AWS_LAMBDA_LOG_GROUP_NAME` 및 `AWS_LAMBDA_LOG_STREAM_NAME` [환경 변수](configuration-envvars.md#configuration-envvars-runtime)는 Lambda SnapStart 함수에서 사용할 수 없습니다.

## SnapStart를 사용하는 로깅 및 청구 동작 이해
<a name="snapstart-cloudwatch"></a>

SnapStart 함수의 [CloudWatch 로그 스트림](monitoring-cloudwatchlogs.md) 형식에는 몇 가지 차이점이 있습니다.
+ **초기화 로그** — 새 실행 환경이 생성되면 `REPORT`에는 `Init Duration` 필드가 포함되지 않습니다. 이는 Lambda가 함수를 호출할 때가 아니라 버전을 생성할 때 SnapStart 함수를 초기화하기 때문입니다. SnapStart 함수의 경우 `Init Duration` 필드는 `INIT_REPORT` 레코드에 있습니다. 이 레코드에는 `beforeCheckpoint` [런타임 후크](snapstart-runtime-hooks.md)의 지속 시간을 비롯한 [초기화 단계](lambda-runtime-environment.md#runtimes-lifecycle-ib)의 지속 시간 세부 정보가 표시됩니다.
+ **호출 로그** — 새 실행 환경이 생성되면 `REPORT`에는 `Restore Duration`와 `Billed Restore Duration` 필드가 포함됩니다.
  + `Restore Duration`: Lambda가 스냅샷을 복원하고, 런타임을 로드하고, 복원 후 [런타임 후크](snapstart-runtime-hooks.md)를 실행하는 데 걸리는 시간입니다. 스냅샷 복원 프로세스에는 microVM 외부 작업에 소요되는 시간이 포함될 수 있습니다. 이 시간은 `Restore Duration`에서 보고됩니다.
  + `Billed Restore Duration`: Lambda가 런타임을 로드하고 복원 후 [런타임 후크](snapstart-runtime-hooks.md)를 실행하는 데 걸리는 시간입니다.

**참고**  
모든 Lambda 함수와 마찬가지로 함수 핸들러에서 실행하는 코드에는 지속 시간 요금이 적용됩니다. SnapStart 함수의 경우 지속 시간 요금은 핸들러 외부에서 선언된 초기화 코드, 런타임에서 로드하는 데 걸리는 시간, [런타임 후크](snapstart-runtime-hooks.md)에서 실행하는 모든 코드에 적용됩니다.

콜드 스타트 지속 시간은 `Restore Duration`과 `Duration`의 합계입니다.

다음 예는 SnapStart 함수의 지연 시간 백분위수를 반환하는 Lambda Insights 쿼리입니다. Lambda Insights 쿼리에 대한 자세한 내용은 [쿼리를 사용하여 함수 문제를 해결하는 예제 워크플로](monitoring-insights.md#monitoring-insights-queries) 섹션을 참조하세요.

```
filter @type = "REPORT"
  | parse @log /\d+:\/aws\/lambda\/(?<function>.*)/
  | parse @message /Restore Duration: (?<restoreDuration>.*?) ms/
  | stats
count(*) as invocations,
pct(@duration+coalesce(@initDuration,0)+coalesce(restoreDuration,0), 50) as p50,
pct(@duration+coalesce(@initDuration,0)+coalesce(restoreDuration,0), 90) as p90,
pct(@duration+coalesce(@initDuration,0)+coalesce(restoreDuration,0), 99) as p99,
pct(@duration+coalesce(@initDuration,0)+coalesce(restoreDuration,0), 99.9) as p99.9
group by function, (ispresent(@initDuration) or ispresent(restoreDuration)) as coldstart
  | sort by coldstart desc
```

## SnapStart에 대한 X-Ray 활성 추적
<a name="snapstart-xray"></a>

[X-Ray](services-xray.md)를 사용하여 Lambda SnapStart 함수에 대한 요청을 추적할 수 있습니다. SnapStart 함수에 대한 X-Ray 하위 세그먼트에는 몇 가지 차이점이 있습니다.
+ SnapStart 함수에 대한 `Initialization` 하위 세그먼트가 없습니다.
+ `Restore` 하위 세그먼트는 Lambda가 스냅샷을 복원하고, 런타임을 로드하고, 복원 후 [런타임 후크](snapstart-runtime-hooks.md)를 실행하는 데 걸리는 시간을 보여줍니다. 스냅샷 복원 프로세스에는 microVM 외부 작업에 소요되는 시간이 포함될 수 있습니다. 이 시간은 `Restore` 하위 세그먼트에서 보고됩니다. 스냅샷을 복원하기 위해 microVM 외부에서 소요된 시간에 대한 요금은 부과되지 않습니다.

## SnapStart용 텔레메트리 API 이벤트
<a name="snapstart-telemetry"></a>

Lambda는 다음과 같은 SnapStart 이벤트를 [텔레메트리 API](telemetry-api.md)로 전송합니다.
+ [`platform.restoreStart`](telemetry-schema-reference.md#platform-restoreStart) - [`Restore` 단계](lambda-runtime-environment.md#runtimes-lifecycle-restore)가 시작된 시간을 표시합니다.
+ [`platform.restoreRuntimeDone`](telemetry-schema-reference.md#platform-restoreRuntimeDone) - `Restore` 단계가 성공했는지 여부를 표시합니다. Lambda는 런타임이 `restore/next` 런타임 API 요청을 보낼 때 이 로그 메시지를 보냅니다. 가능한 상태로는 성공, 실패 및 시간 초과가 있습니다.
+ [`platform.restoreReport`](telemetry-schema-reference.md#platform-restoreReport) - `Restore` 단계가 지속된 시간과 이 단계에서 청구된 시간(밀리초)이 표시됩니다.

## Amazon API Gateway 및 함수 URL 지표
<a name="snapstart-metrics"></a>

[API Gateway를 사용하여](services-apigateway.md) 웹 API를 생성하는 경우 [IntegrationLatency](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-metrics-and-dimensions.html) 지표를 사용하여 엔드 투 엔드 지연 시간(API Gateway가 요청을 백엔드로 릴레이한 시점부터 백엔드에서 응답을 받는 시점까지의 시간)을 측정할 수 있습니다.

[Lambda 함수 URL](urls-configuration.md)을 사용하는 경우 [UrlRequestLatency](urls-monitoring.md) 지표를 사용하여 엔드 투 엔드 지연 시간(함수 URL이 요청을 수신한 시점부터 함수 URL이 응답을 반환하는 시점까지의 시간)을 측정할 수 있습니다.

# Lambda SnapStart의 보안 모델
<a name="snapstart-security"></a>

Lambda SnapStart는 저장 시 암호화를 지원합니다. Lambda는 AWS KMS key를 사용하여 스냅샷을 암호화합니다. 기본적으로 Lambda는 AWS 관리형 키를 사용합니다. 이 기본 동작이 워크플로에 적합한 경우 다른 작업을 설정할 필요가 없습니다. 그렇지 않으면 [create-function](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/create-function.html) 또는 [update-function-configuration](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-configuration.html) 명령에 `--kms-key-arn` 옵션을 사용하여 AWS KMS 고객 관리형 키를 제공할 수 있습니다. KMS 키의 교체를 제어하거나 KMS 키를 관리하기 위한 조직의 요구 사항을 충족하기 위해 이 작업을 수행할 수 있습니다. 고객 관리형 키에는 표준 AWS KMS 요금이 발생합니다. 자세한 내용은 [AWS Key Management Service 요금](https://aws.amazon.com/kms/pricing/)을 참조하십시오.

SnapStart 함수 또는 함수 버전을 삭제하면 해당 함수 또는 함수 버전에 대한 모든 `Invoke` 요청이 실패합니다. Lambda는 일반 데이터 보호 규정(GDPR)에 따라, 삭제된 스냅샷에 연결된 모든 리소스를 제거합니다.

# Lambda SnapStart 성능 극대화
<a name="snapstart-best-practices"></a>

**Topics**
+ [성능 튜닝](#snapstart-tuning)
+ [네트워킹 모범 사례](#snapstart-networking)

## 성능 튜닝
<a name="snapstart-tuning"></a>

SnapStart의 이점을 극대화하려면 런타임에 대해 다음 코드 최적화 권장 사항을 고려합니다.

**참고**  
SnapStart는 대규모 함수 호출에서 사용할 때 가장 효과적입니다. 자주 간접 호출되지 않는 함수에서는 동일한 성능 향상이 이루어지지 않을 수 있습니다.

### Java
<a name="snapstart-tuning-java"></a>

SnapStart의 이점을 극대화하려면 함수 핸들러 대신 초기화 코드에서 시작 지연 시간에 영향을 미치는 리소스를 초기화하고 종속 항목을 미리 로드하는 것이 좋습니다. 이렇게 하면 과도한 클래스 로딩과 관련한 지연 시간이 호출 경로 외부로 오프로드되어 SnapStart를 사용한 시작 성능이 최적화됩니다.

초기화 중에 리소스 또는 종속 항목을 미리 로드할 수 없는 경우 더미 간접 호출을 통해 미리 로드하는 것이 좋습니다. 이렇게 하려면 AWS Labs GitHub 리포지토리의 [Pet Store 함수](https://github.com/awslabs/aws-serverless-java-container/tree/main/samples/spring/pet-store)에서 가져온 다음 예제와 같이 함수 핸들러 코드를 업데이트합니다.

```
private static SpringLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse> handler;
  static {
      try {
          handler = SpringLambdaContainerHandler.getAwsProxyHandler(PetStoreSpringAppConfig.class);

          // Use the onStartup method of the handler to register the custom filter
          handler.onStartup(servletContext -> {
              FilterRegistration.Dynamic registration = servletContext.addFilter("CognitoIdentityFilter", CognitoIdentityFilter.class);
              registration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), false, "/*");
          });

          // Send a fake Amazon API Gateway request to the handler to load classes ahead of time
          ApiGatewayRequestIdentity identity = new ApiGatewayRequestIdentity();
          identity.setApiKey("foo");
          identity.setAccountId("foo");
          identity.setAccessKey("foo");

          AwsProxyRequestContext reqCtx = new AwsProxyRequestContext();
          reqCtx.setPath("/pets");
          reqCtx.setStage("default");
          reqCtx.setAuthorizer(null);
          reqCtx.setIdentity(identity);

          AwsProxyRequest req = new AwsProxyRequest();
          req.setHttpMethod("GET");
          req.setPath("/pets");
          req.setBody("");
          req.setRequestContext(reqCtx);

          Context ctx = new TestContext();
          handler.proxy(req, ctx);


      } catch (ContainerInitializationException e) {
          // if we fail here. We re-throw the exception to force another cold start
          e.printStackTrace();
          throw new RuntimeException("Could not initialize Spring framework", e);
      }
  }
```

### Python
<a name="snapstart-tuning-python"></a>

SnapStart의 이점을 극대화하려면 Python 함수 내에서 효율적인 코드 구성 및 리소스 관리에 집중합니다. 일반적인 지침으로 [초기화 단계](lambda-runtime-environment.md#runtimes-lifecycle-ib) 중에 과중한 계산 태스크를 수행합니다. 이 접근 방식은 간접 호출 경로에서 시간이 오래 걸리는 작업을 제거하여 전체 함수 성능을 개선합니다. 이 전략을 효과적으로 구현하려면 다음 모범 사례를 사용하는 것이 좋습니다.
+ 함수 핸들러 외부에서 종속성을 가져옵니다.
+ 핸들러 외부에서 `boto3` 인스턴스를 생성합니다.
+ 핸들러를 간접 호출하기 전에 정적 리소스 또는 구성을 초기화합니다.
+ 외부 파일 다운로드, Django와 같은 프레임워크 사전 로드 또는 기계 학습 모델 로드와 같은 리소스 집약적 태스크에 대해 스냅샷 생성 전 [런타임 후크](snapstart-runtime-hooks-python.md)를 사용하는 방법을 고려합니다.

**Example - SnapStart에 대한 Python 함수 최적화**  

```
# Import all dependencies outside of Lambda handler
from snapshot_restore_py import register_before_snapshot
import boto3
import pandas
import pydantic

# Create S3 and SSM clients outside of Lambda handler
s3_client = boto3.client("s3")

# Register the function to be called before snapshot
@register_before_snapshot
def download_llm_models():
    # Download an object from S3 and save to tmp
    # This files will persist in this snapshot
    with open('/tmp/FILE_NAME', 'wb') as f:
        s3_client.download_fileobj('amzn-s3-demo-bucket', 'OBJECT_NAME', f)
    ...

def lambda_handler(event, context):
    ...
```

### .NET
<a name="snapstart-tuning-dotnet"></a>

Just-in-Time(JIT) 컴파일 및 어셈블리 로드 시간을 줄이려면 `RegisterBeforeCheckpoint` [런타임 후크](snapstart-runtime-hooks-dotnet.md)에서 함수 핸들러를 호출하는 방법을 고려합니다. .NET 계층형 컴파일의 작동 방식 때문에 다음 예제와 같이 핸들러를 여러 번 간접 호출하여 최적의 결과를 얻을 수 있습니다.

**중요**  
더미 함수 간접 호출로 비즈니스 트랜잭션 시작과 같은 의도하지 않은 부작용이 발생하지 않도록 하세요.

**Example**  

```
public class Function
{
    public Function()
    {
        Amazon.Lambda.Core.SnapshotRestore.RegisterBeforeSnapshot(FunctionWarmup);
    }

    // Warmup method that calls the function handler before snapshot to warm up the .NET code and runtime.
    // This speeds up future cold starts after restoring from a snapshot.

    private async ValueTask FunctionWarmup()
    {
        var request = new APIGatewayProxyRequest
        {
            Path = "/heathcheck",
            HttpMethod = "GET"
        };

        for (var i = 0; i < 10; i++)
        {
            await FunctionHandler(request, null);
        }
    }

    public async Task<APIGatewayProxyResponse> FunctionHandler(APIGatewayProxyRequest request, ILambdaContext context)
    {
        //
        // Process HTTP request
        // 

        var response = new APIGatewayProxyResponse
        {
            StatusCode = 200
        };
        
        return await Task.FromResult(response);
    }
}
```

## 네트워킹 모범 사례
<a name="snapstart-networking"></a>

Lambda가 스냅샷에서 함수를 재개할 때, 초기화 단계에서 함수가 설정한 연결 상태는 보장되지 않습니다. 대부분의 경우 AWS SDK가 설정한 네트워크 연결이 자동으로 재개됩니다. 다른 연결의 경우 다음 모범 사례를 따르는 것이 좋습니다.

**네트워크 연결 재설정**  
스냅샷에서 함수를 재개할 때는 항상 네트워크 연결을 재설정합니다. 함수 핸들러에서 네트워크 연결을 재설정하는 것이 좋습니다. 또는 복원 후 [런타임 후크](snapstart-runtime-hooks.md)를 사용할 수도 있습니다.

**호스트 이름을 고유한 실행 환경 식별자로 사용하지 않음**  
실행 환경을 애플리케이션의 고유한 노드 또는 컨테이너로 식별하는 데 `hostname`을 사용하지 않는 것이 좋습니다. SnapStart를 사용하면 단일 스냅샷이 여러 실행 환경의 초기 상태로 사용됩니다. 모든 실행 환경에서는 `InetAddress.getLocalHost()`(Java), `socket.gethostname()`(Python) 및 `Dns.GetHostName()`(.NET)에 대해 동일한 `hostname` 값을 반환합니다. 고유한 실행 환경 ID 또는 `hostname` 값이 필요한 애플리케이션의 경우 함수 핸들러에서 고유한 ID를 생성하는 것이 좋습니다. 또는 복원 후 [런타임 후크](snapstart-runtime-hooks.md)를 사용하여 고유 ID를 생성하고 이 고유 ID를 실행 환경의 식별자로 사용합니다.

**고정 소스 포트에 연결을 바인딩하지 않음**  
네트워크 연결을 고정 소스 포트에 바인딩하지 않는 것이 좋습니다. 스냅샷에서 함수가 재개되면 연결이 재설정되고 고정 소스 포트에 바인딩된 네트워크 연결이 실패할 수 있습니다.

**Java DNS 캐시를 사용하지 않음**  
Lambda 함수는 이미 DNS 응답을 캐싱하고 있습니다. SnapStart에 다른 DNS 캐시를 사용하는 경우 스냅샷에서 함수를 재개할 때 연결 시간 초과가 발생할 수 있습니다.

`java.util.logging.Logger` 클래스는 JVM DNS 캐시를 간접적으로 활성화할 수 있습니다. 기본 설정을 재정의하려면 `logger` 초기화 전에 [networkaddress.cache.ttl](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/net/InetAddress.html#inetaddress-caching-heading)을 0으로 설정하십시오. 예제:

```
public class MyHandler {
  // first set TTL property
  static{
   java.security.Security.setProperty("networkaddress.cache.ttl" , "0");
  }
 // then instantiate logger
  var logger = org.apache.logging.log4j.LogManager.getLogger(MyHandler.class);
}
```

Java 11 런타임에서 `UnknownHostException` 오류를 방지하려면 `networkaddress.cache.negative.ttl`을 0으로 설정하는 것이 좋습니다. Java 17 이상 런타임에서는 이 단계가 필요하지 않습니다. `AWS_LAMBDA_JAVA_NETWORKADDRESS_CACHE_NEGATIVE_TTL=0` 환경 변수를 사용하여 Lambda 함수에 대해 이 속성을 설정할 수 있습니다.

JVM DNS 캐시를 비활성화해도 Lambda의 관리형 DNS 캐싱은 비활성화되지 않습니다.

# Lambda 함수에 대한 SnapStart 오류 문제 해결
<a name="snapstart-troubleshooting"></a>

이 페이지에서는 스냅샷 생성 오류, 시간 초과 오류, 내부 서비스 오류 등 Lambda SnapStart를 사용할 때 발생하는 일반적인 문제에 대해 설명합니다.

## SnapStartNotReadyException
<a name="snapstartnotreadyexception"></a>

**오류:** 간접 호출 20150331 작업을 직접적으로 간접 호출할 때 오류 발생(SnapStartNotReadyException): Lambda가 함수를 초기화하는 중입니다. 함수 상태가 ACTIVE가 되면 간접적으로 간접 호출할 준비가 된 것입니다.

### 일반적인 원인
<a name="snapstartnotreadyexception-cause"></a>

이 오류는 `Inactive` [상태](snapstart-activate.md#snapstart-function-states)인 함수 버전을 간접적으로 간접 호출하려고 할 때 발생합니다. 함수 버전이 14일 동안 간접 호출되지 않았거나 Lambda가 주기적으로 실행 환경을 재활용하는 경우 `Inactive` 상태가 됩니다.

### 해결 방법
<a name="snapstartnotreadyexception-resolution"></a>

함수 버전이 `Active` 상태에 도달할 때까지 기다린 후 다시 간접 호출하세요.

## SnapStartTimeoutException
<a name="snapstart-invocation-failure"></a>

**문제:** SnapStart 함수 버전을 간접적으로 간접 호출하려고 하면 `SnapStartTimeoutException`이 발생합니다.

### 일반적인 원인
<a name="snapstart-invocation-failure-cause"></a>

[복원](lambda-runtime-environment.md#runtimes-lifecycle-restore) 단계에서 Lambda는 Java 런타임을 복원하고 복원 후 [런타임 후크](snapstart-runtime-hooks.md)를 실행합니다. 복원 후 런타임 후크가 10초 넘게 실행되면 `Restore` 단계의 제한 시간이 초과되고 함수를 간접 호출하려고 할 때 오류가 발생합니다. 네트워크 연결 및 자격 증명 문제로 인해 `Restore` 단계가 시간 초과될 수도 있습니다.

### 해결 방법
<a name="snapstart-invocation-failure-resolution"></a>

함수의 CloudWatch 로그에서 [복원](lambda-runtime-environment.md#runtimes-lifecycle-restore) 단계 중에 발생한 시간 초과 오류가 있는지 확인하세요. 모든 복원 후 런타임 후크가 10초 이내에 완료되어야 합니다.

**Example CloudWatch 로그**  

```
{ "cause": "Lambda couldn't restore the snapshot within the timeout limit. (Service: Lambda, Status Code: 408, Request ID: 11a222c3-410f-427c-ab22-931d6bcbf4f2)", "error": "Lambda.SnapStartTimeoutException"}
```

## 500 내부 서비스 오류
<a name="snapstart-500-error"></a>

**오류:** 동시 스냅샷 생성 한도에 도달하여 Lambda에서 새 스냅샷을 생성할 수 없습니다.

### 일반적인 원인
<a name="snapstart-500-error-cause"></a>

500 오류는 함수나 코드에 문제가 있는 것이 아니라 Lambda 서비스 자체의 내부 오류입니다. 이러한 오류는 종종 간헐적으로 발생합니다.

### 해결 방법
<a name="snapstart-500-error-resolution"></a>

함수 버전을 다시 게시해 보세요.

## 401 권한이 없음
<a name="snapstart-401-unauthorized"></a>

**오류:** 잘못된 세션 토큰 또는 헤더 키

### 일반적인 원인
<a name="snapstart-401-unauthorized-cause"></a>

이 오류는 Lambda SnapStart와 함께 [AWS Systems Manager Parameter Store 및 AWS Secrets Manager 확장](with-secrets-manager.md)을 사용할 때 발생합니다.

### 해결 방법
<a name="snapstart-401-unauthorized-resolution"></a>

AWS Systems Manager Parameter Store와 AWS Secrets Manager 확장은 SnapStart와 호환되지 않습니다. 이 확장은 함수 초기화 중 AWS Secrets Manager와 통신하기 위한 자격 증명을 생성하므로 SnapStart와 함께 사용하면 만료된 자격 증명 오류가 발생합니다.

## UnknownHostException(Java)
<a name="snapstart-dns-caching"></a>

**오류:** HTTP 요청을 실행할 수 없음: `abc.us-east-1.amazonaws.com`에 대한 인증서가 주체 대체 이름 중 어느 것과도 일치하지 않습니다.

### 일반적인 원인
<a name="snapstart-dns-caching-cause"></a>

Lambda 함수는 이미 DNS 응답을 캐싱하고 있습니다. SnapStart에 다른 DNS 캐시를 사용하는 경우 스냅샷에서 함수를 재개할 때 연결 시간 초과가 발생할 수 있습니다.

### 해결 방법
<a name="snapstart-dns-caching-resolution"></a>

Java 11 런타임에서 `UnknownHostException` 오류를 방지하려면 `networkaddress.cache.negative.ttl`을 0으로 설정하는 것이 좋습니다. Java 17 이상 런타임에서는 이 단계가 필요하지 않습니다. `AWS_LAMBDA_JAVA_NETWORKADDRESS_CACHE_NEGATIVE_TTL=0` 환경 변수를 사용하여 Lambda 함수에 대해 이 속성을 설정할 수 있습니다.

## 스냅샷 생성 실패
<a name="snapstart-creation-failure"></a>

**오류:** AWS Lambda가 SnapStart 함수를 간접적으로 간접 호출할 수 없습니다. 이 오류가 지속되면 함수의 CloudWatch 로그에서 초기화 오류가 있는지 확인하세요.

### 해결 방법
<a name="snapstart-creation-failure-resolution"></a>

함수의 Amazon CloudWatch Logs에서 체크포인트 전 [런타임 후크](snapstart-runtime-hooks.md) 제한 시간 초과가 발생하는지 검토합니다. 새 함수 버전을 게시하여 문제를 해결할 수도 있습니다.

## 스냅샷 생성 지연
<a name="snapstart-creation-latency"></a>

**문제:** 새로운 함수 버전을 게시하면 해당 함수는 오랫동안 `Pending` [상태](snapstart-activate.md#snapstart-function-states)로 유지됩니다.

### 일반적인 원인
<a name="snapstart-creation-latency-cause"></a>

Lambda가 스냅샷을 생성할 때 초기화 코드를 최대 15분 동안 실행할 수 있습니다. 시간 제한은 130초 또는 [구성된 함수 제한 시간](configuration-timeout.md)(최대 900초) 중 더 높은 값입니다.

함수가 [VPC에 연결](configuration-vpc.md#configuration-vpc-attaching)된 경우 Lambda는 함수가 `Active` 상태가 되기 전에 네트워크 인터페이스를 생성해야 할 수도 있습니다. 함수가 `Pending` 상태인 동안 함수 버전을 간접적으로 간접 호출하려고 하면 409 `ResourceConflictException`이 발생할 수 있습니다. 함수가 Amazon API Gateway 엔드포인트를 사용하여 간접적으로 간접 호출되는 경우 API Gateway에서 500 오류가 발생할 수 있습니다.

### 해결 방법
<a name="snapstart-creation-latency-resolution"></a>

함수 버전이 초기화될 때까지 15분 이상 기다렸다가 간접적으로 호출하세요.