

# AWS Lambda에 대한 사용자 지정 런타임 빌드
<a name="runtimes-custom"></a>

AWS Lambda 런타임은 모든 프로그래밍 언어로 구현할 수 있습니다. 런타임은 함수가 간접 호출될 때 Lambda 함수의 핸들러 메서드를 실행하는 프로그램입니다. 런타임은 함수의 배포 패키지 또는 [계층](chapter-layers.md)에 포함될 수 있습니다. Lambda 함수를 생성할 때 [OS 전용 런타임](runtimes-provided.md)(`provided` 런타임 제품군)을 선택합니다.

**참고**  
사용자 지정 런타임을 생성하는 작업은 고급 사용 사례입니다. 네이티브 바이너리로 컴파일하거나 타사 상용 런타임을 사용하는 방법에 대한 자세한 내용은 [Lambda의 OS 전용 런타임을 사용해야 하는 경우](runtimes-provided.md) 섹션을 참조하세요.

사용자 지정 런타임 배포 프로세스에 대한 자세한 내용은 [자습서: 사용자 지정 런타임 빌드](runtimes-walkthrough.md) 섹션을 참조하세요.

**Topics**
+ [요구 사항](#runtimes-custom-build)
+ [사용자 지정 런타임에서 응답 스트리밍 구현](#runtimes-custom-response-streaming)
+ [Lambda 관리형 인스턴스에 대한 사용자 지정 런타임 빌드](#runtimes-custom-managed-instances)

## 요구 사항
<a name="runtimes-custom-build"></a>

사용자 지정 런타임에서는 특정 초기화 및 처리 작업을 완료해야 합니다. 런타임은 함수의 설정 코드를 실행하고, 환경 변수에서 핸들러 이름을 읽고, Lambda 런타임 API에서 호출 이벤트를 읽습니다. 런타임은 이벤트 데이터를 함수 핸들러에 전달하고 핸들러의 응답을 Lambda에 다시 게시합니다.

### 초기화 작업
<a name="runtimes-custom-initialization"></a>

초기화 작업은 [함수의 인스턴스당](lambda-runtime-environment.md) 한 번씩 실행되어 호출을 처리할 수 있는 환경을 준비합니다.
+ **설정 검색** – 환경 변수를 읽어 함수 및 환경에 관한 세부 정보를 확인합니다.
  + `_HANDLER` – 함수의 구성에서 핸들러에 대한 위치입니다. 표준 형식은 `file.method`이며, 여기서 `file`은 확장명이 없는 파일의 이름이고 `method`는 파일에 정의된 메서드 또는 함수의 이름입니다.
  + `LAMBDA_TASK_ROOT` – 함수 코드가 포함된 디렉터리입니다.
  + `AWS_LAMBDA_RUNTIME_API` – 런타임 API의 호스트 및 포트입니다.

  사용 가능한 변수의 전체 목록은 [정의된 런타임 환경 변수](configuration-envvars.md#configuration-envvars-runtime) 섹션을 참조하세요.
+ **함수 초기화** – 핸들러 파일을 로드하고 이 파일에 포함된 전역적 또는 정적 코드를 실행합니다. 함수는 SDK 클라이언트 및 데이터베이스 연결과 같은 정적 리소스를 한 번 생성해야 하며, 다중 호출 시 그러한 리소스를 다시 사용해야 합니다.
+ **오류 처리** – 오류가 발생하면 [초기화 오류](runtimes-api.md#runtimes-api-initerror) API를 호출하고 즉시 종료하세요.

초기화 횟수는 청구 대상인 실행 시간 및 시간 초과에 반영됩니다. 실행으로 인해 새 함수 인스턴스의 초기화가 트리거되면 로그 및 [AWS X-Ray 추적](services-xray.md)에서 초기화 시간을 볼 수 있습니다.

**Example log**  

```
REPORT RequestId: f8ac1208... Init Duration: 48.26 ms   Duration: 237.17 ms   Billed Duration: 300 ms   Memory Size: 128 MB   Max Memory Used: 26 MB
```

### 작업 처리
<a name="runtimes-custom-processing"></a>

런타임은 실행 중에 [Lambda 런타임 인터페이스](runtimes-api.md)를 사용하여 수신 이벤트를 관리하고 오류를 보고합니다. 초기화 작업을 완료한 후, 런타임은 수신 이벤트를 루프에서 처리합니다. 런타임 코드에서 다음 단계를 순서대로 수행합니다.
+ **이벤트 가져오기** – 다음 이벤트를 가져오려면 다음 [호출](runtimes-api.md#runtimes-api-next) API를 호출합니다. 응답 본문에는 이벤트 데이터가 포함됩니다. 응답 헤더에는 요청 ID 및 기타 정보가 포함됩니다.
+ **트레이스 헤더 전파** – API 응답의 `Lambda-Runtime-Trace-Id` 헤더에서 X-Ray 트레이스 헤더를 가져옵니다. `_X_AMZN_TRACE_ID` 환경 변수를 동일한 값으로 로컬로 설정합니다. X-Ray SDK는 이 값을 사용하여 서비스 간에 추적 데이터를 연결합니다.
+ **컨텍스트 객체 생성** – API 응답에서 환경 변수 및 헤더의 컨텍스트 정보를 사용하여 객체를 생성합니다.
+ **함수 핸들러 간접 호출** – 이벤트 및 컨텍스트 객체를 핸들러에 전달합니다.
+ **응답 처리** – [호출 응답](runtimes-api.md#runtimes-api-response) API를 호출하여 핸들러의 응답을 게시합니다.
+ **오류 처리** – 오류가 발생하면 [호출 오류](runtimes-api.md#runtimes-api-invokeerror) API를 호출합니다.
+ **정리** – 사용하지 않은 리소스를 릴리스하거나 다른 서비스로 데이터를 전송하거나 혹은 다음 이벤트를 가져오기 전에 추가 작업을 수행하세요.

### 진입점
<a name="runtimes-custom-bootstrap"></a>

사용자 지정 런타임의 진입점은 `bootstrap`이라는 이름의 실행 파일입니다. 부트스트랩 파일은 런타임일 수 있으며 혹은 런타임을 생성하는 다른 파일을 간접 호출할 수도 있습니다. 배포 패키지의 루트에 `bootstrap` 파일이 없는 경우 Lambda는 함수 계층에서 파일을 찾습니다. `bootstrap` 파일이 없거나 실행할 수 없는 경우, 함수는 간접 호출 시 `Runtime.InvalidEntrypoint` 오류를 반환합니다.

다음은 번들 버전의 Node.js를 사용하여 별도의 `runtime.js` 파일에서 JavaScript 런타임을 실행하는 `bootstrap` 파일 예제입니다.

**Example 부트스트랩**  

```
#!/bin/sh
    cd $LAMBDA_TASK_ROOT
    ./node-v11.1.0-linux-x64/bin/node runtime.js
```

## 사용자 지정 런타임에서 응답 스트리밍 구현
<a name="runtimes-custom-response-streaming"></a>

[응답 스트리밍 함수](configuration-response-streaming.md)의 경우, 런타임이 클라이언트에 부분 응답을 스트리밍하고 페이로드를 청크 단위로 반환할 수 있도록 `response` 및 `error` 엔드포인트의 동작이 약간 수정되었습니다. 특정 동작에 대한 자세한 내용은 다음 섹션을 참조하세요.
+ `/runtime/invocation/AwsRequestId/response` - 런타임에서 `Content-Type` 헤더를 전파하여 클라이언트로 전송합니다. Lambda는 HTTP/1.1 청크 분할 전송 인코딩을 통해 응답 페이로드를 청크로 반환합니다. Lambda로 응답을 스트리밍하려면 런타임에서 다음을 수행해야 합니다.
  + `Lambda-Runtime-Function-Response-Mode` HTTP 헤더를 `streaming`로 설정합니다.
  + `Transfer-Encoding` 헤더를 `chunked`로 설정합니다.
  + HTTP/1.1 청크 분할 전송 인코딩 사양을 준수하는 응답을 작성합니다.
  + 응답을 성공적으로 작성한 후 기본 연결을 닫습니다.
+ `/runtime/invocation/AwsRequestId/error` - 이 런타임은 이 엔드포인트를 사용하여 `Transfer-Encoding` 헤더도 허용하는 Lambda에 함수 또는 런타임 오류를 보고할 수 있습니다. 이 엔드포인트는 런타임이 호출 응답 전송을 시작하기 전에만 호출할 수 있습니다.
+ `/runtime/invocation/AwsRequestId/response`의 오류 트레일러를 사용하여 미드스트림 오류 보고 – 이 런타임은 호출 응답 작성을 시작한 후 발생하는 오류를 보고하기 위해 선택적으로 `Lambda-Runtime-Function-Error-Type` 및 `Lambda-Runtime-Function-Error-Body`라는 HTTP 후행 헤더를 연결할 수 있습니다. Lambda는 이를 성공적인 응답으로 간주하고 런타임이 클라이언트에 제공하는 오류 메타데이터를 전달합니다.
**참고**  
후행 헤더를 첨부하려면 런타임이 HTTP 요청 시작 시 `Trailer` 헤더 값을 설정해야 합니다. 이는 HTTP/1.1 청크 분할 전송 인코딩 사양의 요구 사항입니다.
  + `Lambda-Runtime-Function-Error-Type` – 런타임에서 발생한 오류 유형입니다. 이 헤더는 문자열 값으로 구성됩니다. Lambda는 모든 문자열을 허용하지만 *<category.reason>* 형식을 사용하는 것이 좋습니다. 예를 들어 `Runtime.APIKeyNotFound`입니다.
  + `Lambda-Runtime-Function-Error-Body` - 오류에 대한 base64로 인코딩된 정보입니다.

## Lambda 관리형 인스턴스에 대한 사용자 지정 런타임 빌드
<a name="runtimes-custom-managed-instances"></a>

Lambda 관리형 인스턴스는 Lambda(기본값) 함수와 동일한 런타임 API를 사용합니다. 하지만 관리형 인스턴스의 동시 실행 모델을 지원하기 위해 사용자 지정 런타임을 구현하는 방법에는 큰 차이점이 있습니다.

### 동시 요청 처리
<a name="runtimes-custom-managed-instances-concurrency"></a>

관리형 인스턴스에 대한 사용자 지정 런타임을 빌드할 때의 주된 차이점은 동시 간접 호출 지원입니다. 런타임이 한 번에 하나의 간접 호출을 처리하는 Lambda(기본값) 함수와 달리 관리형 인스턴스는 단일 실행 환경 내에서 여러 개의 간접 호출을 동시에 처리할 수 있습니다.

사용자 지정 런타임은 다음 사항을 충족해야 합니다.
+ **동시 `/next` 요청 지원** - 런타임은 `AWS_LAMBDA_MAX_CONCURRENCY` 환경 변수에 지정된 제한까지 [다음 간접 호출](runtimes-api.md#runtimes-api-next) API를 여러 번 동시에 호출할 수 있습니다.
+ **동시 `/response` 요청 처리** - 여러 개의 간접 호출이 [간접 호출 응답](runtimes-api.md#runtimes-api-response) API를 동시에 호출할 수 있습니다.
+ **스레드 안전 요청 처리 구현** - 공유 리소스 및 상태를 적절하게 관리하여 동시 간접 호출이 서로 방해가 되지 않도록 해야 합니다.
+ **고유한 요청 ID 사용** - `Lambda-Runtime-Aws-Request-Id` 헤더를 사용하여 각 간접 호출을 개별적으로 추적하여 응답을 해당 요청과 일치시킵니다.

### 구현 패턴
<a name="runtimes-custom-managed-instances-implementation"></a>

관리형 인스턴스 런타임의 일반적인 구현 패턴에는 동시 간접 호출을 처리하기 위한 작업자 스레드 또는 프로세스 생성이 포함됩니다.

1. **동시성 제한 읽기** - 초기화 시 `AWS_LAMBDA_MAX_CONCURRENCY` 환경 변수를 읽고 지원할 동시 간접 호출 수를 결정합니다.

1. **작업자 풀 생성** - 동시성 제한과 같은 작업자 풀(스레드, 프로세스 또는 비동기식 태스크)을 초기화합니다.

1. **작업자 처리 루프** - 각 작업자가 독립적으로 수행하는 작업:
   + `/runtime/invocation/next` 직접 호출로 간접 호출 이벤트 가져오기
   + 이벤트 데이터로 함수 핸들러 간접 호출
   + `/runtime/invocation/AwsRequestId/response`에 응답 게시
   + 루프 반복

### 추가 고려 사항
<a name="runtimes-custom-managed-instances-considerations"></a>
+ **로깅 형식** - 관리형 인스턴스는 JSON 로그 형식만 지원합니다. 런타임에서 `AWS_LAMBDA_LOG_FORMAT` 환경 변수를 준수하고 JSON 형식만 사용해야 합니다. 자세한 내용은 [JSON 및 일반 텍스트 로그 형식 구성](monitoring-cloudwatchlogs-logformat.md) 섹션을 참조하세요.
+ **공유 리소스** - `/tmp` 디렉터리와 같은 공유 리소스를 동시 간접 호출에서 사용할 때는 주의해야 합니다. 경합 상황을 방지하기 위해 적절한 잠금 메커니즘을 구현해야 합니다.

Lambda 관리형 인스턴스 실행 환경에 대한 자세한 내용은 [Lambda 관리형 인스턴스 실행 환경 이해](lambda-managed-instances-execution-environment.md) 항목을 참조하세요.