

# Lambda 함수에 대한 응답 스트리밍
<a name="configuration-response-streaming"></a>

Lambda 함수는 기본적으로 [Lambda 함수 URL](urls-configuration.md)을 통해 또는 [InvokeWithResponseStream](https://docs.aws.amazon.com/lambda/latest/api/API_InvokeWithResponseStream.html) API를 사용하여(AWS SDK 또는 API 직접 호출을 통해) 응답 페이로드를 클라이언트로 다시 스트리밍할 수 있습니다. Lambda 함수는 [InvokeWithResponseStream](https://docs.aws.amazon.com/lambda/latest/api/API_InvokeWithResponseStream.html) API를 사용하여 함수를 간접 호출하는 [Amazon API Gateway 프록시 통합](https://docs.aws.amazon.com/apigateway/latest/developerguide/response-transfer-mode-lambda.html)을 통해 응답 페이로드를 스트리밍할 수도 있습니다. 응답 스트리밍은 첫 번째 바이트까지 시간(TTFB) 성능을 개선하여 지연 시간에 민감한 애플리케이션에 도움이 될 수 있습니다. 이는 부분 응답을 사용할 수 있게 되면 클라이언트에 다시 전송할 수 있기 때문입니다. 또한 응답 스트리밍 함수는 버퍼링된 응답의 최대 6MB에 비해 최대 200MB의 페이로드를 반환할 수 있습니다. 응답을 스트리밍하므로 함수가 전체 응답을 메모리에 담을 필요가 없습니다. 응답이 매우 큰 경우 함수에 대해 구성해야 하는 메모리 양을 줄일 수 있습니다.

**참고**  
Lambda 응답 스트리밍은 아직 일부 AWS 리전에서 사용할 수 없습니다. Builder Center의 [리전별 AWS 기능](https://builder.aws.com/build/capabilities)에서 리전별 기능 제공 여부를 참조하세요.

Lambda가 응답을 스트리밍하는 속도는 응답 크기에 따라 달라집니다. 함수 응답의 처음 6MB에 대한 스트리밍 속도에는 제한이 없습니다. 6MB보다 큰 응답의 경우 응답의 나머지 부분에 대역폭 한도가 적용됩니다. 스트리밍 대역폭에 대한 자세한 내용은 [응답 스트리밍에 대한 대역폭 한도](#config-rs-bandwidth-cap) 섹션을 참조하세요.

스트리밍 응답에는 비용이 발생하고 간접 호출 클라이언트 연결이 끊어지면 스트리밍 응답이 중단 또는 중지되지 않습니다. 고객에게는 전체 함수 기간에 대한 요금이 청구되므로 고객은 긴 함수 제한 시간을 구성할 때 주의를 기울여야 합니다.

Lambda는 Node.js 관리형 런타임에서 응답 스트리밍을 지원합니다. Python을 포함한 다른 언어의 경우, [사용자 지정 런타임을 사용자 지정 런타임 API 통합과 함께 사용](runtimes-custom.md#runtimes-custom-response-streaming)하여 응답을 스트리밍하거나 [Lambda Web Adapter](https://github.com/awslabs/aws-lambda-web-adapter)를 사용할 수 있습니다.

**참고**  
Lambda 콘솔을 통해 함수를 테스트할 때 항상 응답이 버퍼링된 것으로 표시됩니다.

**Topics**
+ [응답 스트리밍에 대한 대역폭 한도](#config-rs-bandwidth-cap)
+ [응답 스트리밍과의 VPC 호환성](#config-rs-vpc-compatibility)
+ [응답 스트리밍 지원 Lambda 함수 작성](config-rs-write-functions.md)
+ [Lambda 함수 URL을 사용하여 응답 스트리밍 지원 함수 호출](config-rs-invoke-furls.md)
+ [자습서: 함수 URL을 사용하여 응답 스트리밍 Lambda 함수 생성](response-streaming-tutorial.md)

## 응답 스트리밍에 대한 대역폭 한도
<a name="config-rs-bandwidth-cap"></a>

함수 응답 페이로드의 처음 6MB에는 대역폭 한도가 없습니다. 이 초기 버스트 이후 Lambda는 최대 2MBps의 속도로 응답을 스트리밍합니다. 함수 응답이 6MB를 초과하지 않는 경우 이 대역폭 한도는 적용되지 않습니다.

**참고**  
대역폭 한도는 함수의 응답 페이로드에만 적용되며 함수의 네트워크 액세스에는 적용되지 않습니다.

제한되지 않은 대역폭의 속도는 함수의 처리 속도를 비롯한 여러 요인에 따라 달라집니다. 일반적으로 함수 응답의 처음 6MB에 대해 2MBps보다 높은 속도를 예상할 수 있습니다. 함수가 AWS 외부의 대상으로 응답을 스트리밍하는 경우 스트리밍 속도는 외부 인터넷 연결 속도에 따라서도 달라집니다.

## 응답 스트리밍과의 VPC 호환성
<a name="config-rs-vpc-compatibility"></a>

VPC 환경에서 Lambda 함수를 사용할 경우 응답 스트리밍에 대한 중요한 고려 사항이 있습니다.
+ Lambda 함수 URL은 VPC 환경 내에서 응답 스트리밍을 지원하지 않습니다.
+ `InvokeWithResponseStream` API를 사용하는 AWS SDK를 통해 Lambda 함수를 간접적으로 호출하여 VPC 내에서 응답 스트리밍을 사용할 수 있습니다. 이렇게 하려면 Lambda에 적합한 VPC 엔드포인트를 설정해야 합니다.
+ VPC 환경의 경우, VPC의 리소스와 Lambda 서비스 간의 통신을 활성화하려면 Lambda에 대한 인터페이스 VPC 엔드포인트를 생성해야 합니다.

VPC에서 응답 스트리밍을 위한 일반적인 아키텍처는 다음과 같습니다.

```
Client in VPC -> Interface VPC endpoint for Lambda -> Lambda function -> Response streaming back through the same path
```

# 응답 스트리밍 지원 Lambda 함수 작성
<a name="config-rs-write-functions"></a>

응답 스트리밍 함수의 핸들러 작성은 일반적인 핸들러 패턴과 다릅니다. 스트리밍 함수를 작성할 때 다음을 수행해야 합니다.
+ `awslambda.streamifyResponse()` 데코레이터로 함수를 래핑합니다. `awslambda` 글로벌 객체는 Lambda의 Node.js 런타임 환경에서 제공됩니다.
+ 모든 데이터 처리가 완료되도록 스트림을 정상적으로 종료합니다.

## 응답을 스트리밍하도록 핸들러 함수 구성
<a name="config-rs-write-functions-handler"></a>

Lambda가 함수의 응답을 스트리밍해야 함을 런타임에 나타내려면 함수를 `streamifyResponse()` 데코레이터로 래핑해야 합니다. 그러면 런타임이 응답 스트리밍에 적합한 로직 경로를 사용하고 함수가 응답을 스트리밍할 수 있습니다.

`streamifyResponse()` 데코레이터는 다음 파라미터를 수락하는 함수를 수락합니다.
+ `event` - HTTP 메서드, 쿼리 파라미터 및 요청 본문과 같은 함수 URL의 호출 이벤트에 대한 정보를 제공합니다.
+ `responseStream` - 쓰기 가능한 스트림을 제공합니다.
+ `context` – 호출, 함수 및 실행 환경에 대한 정보를 메서드 및 속성에 제공합니다.

`responseStream` 객체는 [Node.js `writableStream`](https://nodesource.com/blog/understanding-streams-in-nodejs/)입니다. 이러한 스트림과 마찬가지로 `pipeline()` 메서드를 사용해야 합니다.

**참고**  
`awslambda` 글로벌 객체는 Lambda의 Node.js 런타임에서 자동으로 제공되므로 가져올 필요가 없습니다.

**Example 응답 스트리밍 지원 핸들러**  

```
import { pipeline } from 'node:stream/promises';
import { Readable } from 'node:stream';

export const echo = awslambda.streamifyResponse(async (event, responseStream, _context) => {
  // As an example, convert event to a readable stream.
  const requestStream = Readable.from(Buffer.from(JSON.stringify(event)));

  await pipeline(requestStream, responseStream);
});
```

`responseStream`은 스트림에 쓰기를 위한 `write()` 메서드를 제공하지만 가능하면 [https://nodejs.org/api/stream.html#streampipelinesource-transforms-destination-callback](https://nodejs.org/api/stream.html#streampipelinesource-transforms-destination-callback)을 사용하는 것이 좋습니다. `pipeline()`을 사용하면 쓰기 가능한 스트림이 더 빠른 읽기 가능한 스트림에 의해 압도되지 않도록 합니다.

## 스트리밍 종료
<a name="config-rs-write-functions-end"></a>

핸들러가 반환되기 전에 스트림을 제대로 종료해야 합니다. `pipeline()` 메서드가 이를 자동으로 처리합니다.

다른 사용 사례의 경우 `responseStream.end()` 메서드를 호출하여 스트림을 올바르게 종료하세요. 이 메서드는 스트림에 더 이상 데이터를 쓰지 말아야 한다는 신호를 보냅니다. `pipeline()` 또는 `pipe()`를 사용하여 스트림에 쓰는 경우에는 이 메서드가 필요하지 않습니다.

Node.js 24부터 Lambda는 핸들러가 반환되거나 응답 스트림이 종료된 후 해결되지 않은 promise가 완료되는 것을 더 이상 기다리지 않습니다. 함수가 타이머 또는 가져오기와 같은 추가 비동기식 작업에 의존하는 경우 핸들러에서 `await` 작업을 수행해야 합니다.

**Example pipeline()을 사용하여 스트림을 종료하는 예제**  

```
import { pipeline } from 'node:stream/promises';

export const handler = awslambda.streamifyResponse(async (event, responseStream, _context) => {
  await pipeline(requestStream, responseStream);
});
```

**Example pipeline()을 사용하지 않고 스트림을 종료하는 예제**  

```
export const handler = awslambda.streamifyResponse(async (event, responseStream, _context) => {
  responseStream.write("Hello ");
  responseStream.write("world ");
  responseStream.write("from ");
  responseStream.write("Lambda!");
  responseStream.end();
});
```

# Lambda 함수 URL을 사용하여 응답 스트리밍 지원 함수 호출
<a name="config-rs-invoke-furls"></a>

**참고**  
이제 Lambda 함수가 [Amazon API Gateway 프록시 통합](https://docs.aws.amazon.com/apigateway/latest/developerguide/response-transfer-mode-lambda.html)을 통해 응답 페이로드를 스트리밍할 수 있습니다.

함수 URL의 간접 호출 모드를 변경하여 응답 스트리밍 지원 함수를 간접 호출할 수 있습니다. 간접 호출 모드는 Lambda가 함수를 간접 호출하는 데 사용하는 API 작업을 결정합니다. 사용 가능한 간접 호출 모드는 다음과 같습니다.
+ `BUFFERED` - 기본 옵션입니다. Lambda는 `Invoke` API 작업을 사용하여 함수를 간접 호출합니다. 페이로드가 완료되면 호출 결과를 사용할 수 있습니다. 최대 페이로드 크기는 6MB입니다.
+ `RESPONSE_STREAM` - 함수가 페이로드 결과를 사용할 수 있게 되면 스트리밍할 수 있도록 합니다. Lambda는 `InvokeWithResponseStream` API 작업을 사용하여 함수를 간접 호출합니다. 최대 응답 페이로드 크기는 200MB입니다.

`Invoke` API 작업을 직접 간접 호출하여 응답 스트리밍 없이 함수를 간접 호출할 수 있습니다. 그러나 Lambda는 간접 호출 모드를 `BUFFERED`로 변경할 때까지 함수 URL을 통해 들어오는 간접 호출에 대한 모든 응답 페이로드를 스트리밍합니다.

------
#### [ Console ]

**함수 URL의 간접 호출 모드 설정(콘솔)**

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

1. 간접 호출 모드를 설정할 함수의 이름을 선택합니다.

1. **구성(Configuration)** 탭을 선택한 다음, **함수 URL(Function URL)**을 선택합니다.

1. **편집**을 선택하고 **추가 설정**을 선택합니다.

1. **간접 호출 모드**에서 원하는 간접 호출 모드를 선택합니다.

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

------
#### [ AWS CLI ]

**함수 URL의 간접 호출 모드 설정(AWS CLI)**

```
aws lambda update-function-url-config \
  --function-name my-function \
  --invoke-mode RESPONSE_STREAM
```

------
#### [ CloudFormation ]

**함수 URL의 간접 호출 모드 설정(CloudFormation)**

```
MyFunctionUrl:
  Type: AWS::Lambda::Url
  Properties:
    AuthType: AWS_IAM
    InvokeMode: RESPONSE_STREAM
```

------

함수 URL 구성에 대한 자세한 내용은 [Lambda 함수 URL](urls-configuration.md) 섹션을 참조하세요.

# 자습서: 함수 URL을 사용하여 응답 스트리밍 Lambda 함수 생성
<a name="response-streaming-tutorial"></a>

이 자습서에서는 응답 스트림을 반환하는 함수 URL 엔드포인트를 사용하여 .zip 파일 아카이브로 정의된 Lambda 함수를 생성합니다. 함수 구성에 대한 자세한 내용은 [함수 URL](urls-configuration.md) 섹션을 참조하세요.

## 사전 조건
<a name="response-streaming-prepare"></a>

이 자습서에서는 사용자가 기본 Lambda 작업과 Lambda 콘솔에 대해 어느 정도 알고 있다고 가정합니다. 그렇지 않은 경우 [콘솔로 Lambda 함수 생성](getting-started.md#getting-started-create-function)의 지침에 따라 첫 Lambda 함수를 생성합니다.

다음 단계를 완료하려면 [AWS CLI 버전 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)가 필요합니다. 명령과 예상 결과는 별도의 블록에 나열됩니다.

```
aws --version
```

다음 결과가 표시됩니다.

```
aws-cli/2.13.27 Python/3.11.6 Linux/4.14.328-248.540.amzn2.x86_64 exe/x86_64.amzn.2
```

긴 명령의 경우 이스케이프 문자(`\`)를 사용하여 명령을 여러 행으로 분할합니다.

Linux 및 macOS는 선호 셸과 패키지 관리자를 사용합니다.

**참고**  
Windows에서는 Lambda와 함께 일반적으로 사용하는 일부 Bash CLI 명령(예:`zip`)은 운영 체제의 기본 제공 터미널에서 지원되지 않습니다. Ubuntu와 Bash의 Windows 통합 버전을 가져오려면 [Linux용 Windows Subsystem을 설치](https://docs.microsoft.com/en-us/windows/wsl/install-win10)합니다. 이 안내서의 예제 CLI 명령은 Linux 형식을 사용합니다. Windows CLI를 사용하는 경우 인라인 JSON 문서를 포함하는 명령의 형식을 다시 지정해야 합니다.

## 실행 역할 만들기
<a name="response-streaming-create-iam-role"></a>

Lambda 함수에 AWS 리소스에 액세스할 수 있는 권한을 제공하는 [실행 역할](lambda-intro-execution-role.md)을 만듭니다.

**실행 역할을 만들려면**

1. AWS Identity and Access Management(IAM) 콘솔의 [역할 페이지](https://console.aws.amazon.com/iam/home#/roles)를 엽니다.

1. **역할 생성(Create role)**을 선택합니다.

1. 다음 속성을 사용하여 역할을 만듭니다.
   + **신뢰할 수 있는 엔티티 유형** — **AWS서비스**
   + **사용 사례** — **Lambda**
   + **권한** – **AWSLambdaBasicExecutionRole**
   + **역할 이름** – **response-streaming-role**

**AWSLambdaBasicExecutionRole** 정책은 함수가 Amazon CloudWatch Logs에 로그를 쓰는 데 필요한 권한을 가집니다. 역할을 생성한 후 Amazon 리소스 이름(ARN)을 기록해 둡니다. 다음 단계에서 이 정보를 사용할 것입니다.

## 응답 스트리밍 함수 생성(AWS CLI)
<a name="response-streaming-tutorial-create-function-cli"></a>

AWS Command Line Interface(AWS CLI)를 사용하여 함수 URL 엔드포인트로 응답 스트리밍 Lambda 함수를 생성합니다.

**응답을 스트리밍할 수 있는 함수 생성**

1. 다음 코드 예제를 `index.js`라는 파일에 복사합니다. 이 함수는 1초로 구분된 세 개의 응답을 스트리밍합니다.

   ```
   exports.handler = awslambda.streamifyResponse(
   	async (event, responseStream, _context) => {
   		// Metadata is a JSON serializable JS object. Its shape is not defined here.
   		const metadata = {
   		statusCode: 200,
   		headers: {
   			"Content-Type": "application/json",
   			"CustomHeader": "outerspace"
   		}
   		};
   	
   		// Assign to the responseStream parameter to prevent accidental reuse of the non-wrapped stream.
   		responseStream = awslambda.HttpResponseStream.from(responseStream, metadata);
   	
   		responseStream.write("Streaming with Helper \n");
   		await new Promise(r => setTimeout(r, 1000));
   		responseStream.write("Hello 0 \n");
   		await new Promise(r => setTimeout(r, 1000));
   		responseStream.write("Hello 1 \n");
   		await new Promise(r => setTimeout(r, 1000));
   		responseStream.write("Hello 2 \n");
   		await new Promise(r => setTimeout(r, 1000));
   		responseStream.end();
   		await responseStream.finished();
   	}
     );
   ```

1. 배포 패키지를 만듭니다.

   ```
   zip function.zip index.js
   ```

1. `create-function` 명령을 사용해 Lambda 함수를 만듭니다. `--role` 값을 이전 단계의 역할 ARN으로 변경합니다. 이 명령은 함수 제한 시간을 10초로 설정하여 함수가 세 개의 응답을 스트리밍할 수 있도록 합니다.

   ```
   aws lambda create-function \
     --function-name my-streaming-function \
     --runtime nodejs24.x \
     --zip-file fileb://function.zip \
     --handler index.handler \
     --timeout 10 \
     --role arn:aws:iam::123456789012:role/response-streaming-role
   ```

**함수 URL 생성**

1. 함수에 `lambda:InvokeFunctionUrl` 및 `lambda:InvokeFunction` 권한을 부여하는 리소스 기반 정책을 추가합니다. 각 문은 별도의 명령에 추가해야 합니다. `--principal` 값을 AWS 계정 ID로 바꿉니다.

   ```
   aws lambda add-permission \
     --function-name my-streaming-function \
     --action lambda:InvokeFunctionUrl \
     --statement-id UrlPolicyInvokeURL \
     --principal 123456789012 \
     --function-url-auth-type AWS_IAM
   ```

   ```
   aws lambda add-permission \
       --function-name my-streaming-function \
       --action lambda:InvokeFunction \
       --statement-id UrlPolicyInvokeFunction \
       --principal 123456789012
   ```

1. `create-function-url-config` 명령을 사용하여 함수에 대한 URL 엔드포인트를 만듭니다.

   ```
   aws lambda create-function-url-config \
     --function-name my-streaming-function \
     --auth-type AWS_IAM \
     --invoke-mode RESPONSE_STREAM
   ```
**참고**  
`--invoke-mode`에 대한 오류가 발생하는 경우 [최신 버전의 AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)로 업그레이드해야 할 수 있습니다.

## 함수 URL 엔드포인트 테스트
<a name="response-streaming-tutorial-test"></a>

함수를 호출하여 통합을 테스트합니다. 브라우저에서 함수의 URL을 열거나 curl을 사용할 수 있습니다.

```
curl --request GET "https://abcdefghijklm7nop7qrs740abcd.lambda-url.us-east-1.on.aws/" --user "AKIAIOSFODNN7EXAMPLE" --aws-sigv4 "aws:amz:us-east-1:lambda" --no-buffer
```

함수 URL은 `IAM_AUTH` 인증 유형을 사용합니다. 즉, [AWS 액세스 키와 비밀 키](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html)를 모두 사용하여 요청에 서명해야 합니다. 이전 명령에서 `AKIAIOSFODNN7EXAMPLE`을 AWS 액세스 키 ID로 바꿉니다. 메시지가 나타나면 AWS 비밀 키를 입력합니다. AWS 비밀 키가 없으면 [임시 AWS 보안 인증을 대신 사용](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html)할 수 있습니다.

다음과 같은 응답이 표시되어야 합니다.

```
Streaming with Helper 
Hello 0 
Hello 1
Hello 2
```

## 리소스 정리
<a name="cleanup"></a>

이 자습서 용도로 생성한 리소스를 보관하고 싶지 않다면 지금 삭제할 수 있습니다. 더 이상 사용하지 않는 AWS 리소스를 삭제하면 AWS 계정에 불필요한 요금이 발생하는 것을 방지할 수 있습니다.

**집행 역할 삭제**

1. IAM 콘솔에서 [역할 페이지](https://console.aws.amazon.com/iam/home#/roles)를 엽니다.

1. 생성한 실행 역할을 선택합니다.

1. **삭제**를 선택합니다.

1. 텍스트 입력 필드에 역할의 이름을 입력하고 **Delete**(삭제)를 선택합니다.

**Lambda 함수를 삭제하려면**

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

1. 생성한 함수를 선택합니다.

1. **작업**, **삭제**를 선택합니다.

1. 텍스트 입력 필드에 **confirm**를 입력하고 **Delete**(삭제)를 선택합니다.