

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# Lambda 函數的回應串流
<a name="configuration-response-streaming"></a>

Lambda 函數可以透過 [Lambda 函數 URLs](urls-configuration.md) 或使用 [InvokeWithResponseStream](https://docs.aws.amazon.com/lambda/latest/api/API_InvokeWithResponseStream.html) API （透過 AWS SDK 或直接 API 呼叫），將回應承載原生串流回用戶端。您的 Lambda 函數也可以透過 [Amazon API Gateway 代理整合](https://docs.aws.amazon.com/apigateway/latest/developerguide/response-transfer-mode-lambda.html)串流回應承載，該整合使用 [InvokeWithResponseStream](https://docs.aws.amazon.com/lambda/latest/api/API_InvokeWithResponseStream.html) API 來叫用您的函數。透過提高第一個位元組時間 (TTFB) 效能，回應串流有益於延遲敏感應用程式。這是因為您可以在部分回應可用時將其傳回給用戶端。此外，相較於緩衝回應的 6 MB 上限，回應串流函式最多可傳回 200 MB 的承載。串流回應也意味著您的函數不需要將整個回應放在記憶體裡。若是非常大的回應，這有助於減少您需要為函數設定的記憶體容量。

**注意**  
Lambda 回應串流尚未全面提供 AWS 區域。請參閱依[AWS 區域劃分的 Builder Center 功能](https://builder.aws.com/build/capabilities)，以取得依區域劃分的功能可用性。

Lambda 串流回應的速度取決於回應的大小。函式回應的串流速度在前 6 MB 不受限制。若回應大於 6 MB，則其餘的回應會受到頻寬上限的限制。如需串流頻寬的詳細資訊，請參閱[回應串流的頻寬限制](#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>

函式回應承載的前 6 MB 不受頻寬限制。在最初的高頻寬流量後，Lambda 會以最高 2 MBps 的速率串流您的回應。如果函式回應一直都沒超過 6 MB，則永遠不會適用此頻寬限制。

**注意**  
頻寬限制僅適用於函數的回應有效負載，不適用於函數的網路存取。

無頻寬上限的速率取決於諸多因素 (包括函數的處理速度)。一般來說，您可以預期函式回應前 6 MB 的速率會高於 2 Mbps。如果您的函數正在將回應串流到 以外的目的地 AWS，則串流速率也取決於外部網際網路連線的速度。

## VPC 與回應串流的相容性
<a name="config-rs-vpc-compatibility"></a>

在 VPC 環境中使用 Lambda 函式時，回應串流需注意下列重要考量事項：
+ Lambda 函式 URL 不支援 VPC 環境中的回應串流。
+ 您可以使用 `InvokeWithResponseStream` API 透過 AWS SDK 叫用 Lambda 函數，在 VPC 內使用回應串流。這需要為 Lambda 設定適當的 VPC 端點。
+ 對於 VPC 環境，您需要為 Lambda 建立介面 VPC 端點，用以啟用 VPC 環境中資源與 Lambda 服務之間的通訊。

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` – 提供函數 URL 調用事件的相關資訊，例如 HTTP 方法、查詢參數和請求內文。
+ `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 不會在處理常式傳回或回應串流結束之後，再等待未解決的承諾完成。如果您的函數依賴其他非同步操作，例如計時器或擷取，您應該在處理常式中`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 操作調用您的函數。承載完成時，即可使用調用結果。承載大小上限為 6 MB。
+ `RESPONSE_STREAM` – 啟用您的函數，當承載結果變得可用時串流它們。Lambda 會使用 `InvokeWithResponseStream` API 操作調用您的函數。回應承載大小上限為 200 MB。

您仍然可以透過直接呼叫 `Invoke` API 操作來調用函數而無需回應串流。不過，Lambda 會串流透過函數 URL 調用的所有回應承載，直到您將調用模式變更為 `BUFFERED`。

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

**設定函數 URL 的調用模式 (主控台)**

1. 開啟 Lambda 主控台中的[函數頁面](https://console.aws.amazon.com/lambda/home#/functions)。

1. 選擇您要為其設定調用模式的函數名稱。

1. 選擇 **Configuration** (組態) 標籤，然後選擇 **Function URL** (函數 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>

在本教學課程中，您會建立格式為 .zip 封存檔的 Lambda 函數，其包含的函數 URL 端點會傳回回應串流。如需設定函數 URL 的詳細資訊，請參閱 [函數 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 上，使用您偏好的 shell 和套件軟體管理工具。

**注意**  
在 Windows 中，作業系統的內建終端不支援您常與 Lambda 搭配使用的某些 Bash CLI 命令 (例如 `zip`)。若要取得 Ubuntu 和 Bash 的 Windows 整合版本，請[安裝適用於 Linux 的 Windows 子系統](https://docs.microsoft.com/en-us/windows/wsl/install-win10)。本指南中的 CLI 命令範例使用 Linux 格式。如果您使用的是 Windows CLI，必須重新格式化包含內嵌 JSON 文件的命令。

## 建立執行角色
<a name="response-streaming-create-iam-role"></a>

建立[執行角色](lambda-intro-execution-role.md)，授予您的 Lambda 函數存取 AWS 資源的許可。

**若要建立執行角色**

1. 開啟 AWS Identity and Access Management (IAM) 主控台的 [角色](https://console.aws.amazon.com/iam/home#/roles) 頁面。

1. 選擇建**立角色**。

1. 建立具備下列屬性的角色：
   + **信任的實體類型**：**AWS 服務**
   + **使用案例**：**Lambda**
   + **許可** – **AWSLambdaBasicExecutionRole**
   + **角色名稱** - **response-streaming-role**。

**AWSLambdaBasicExecutionRole** 政策具有函數將日誌寫入 Amazon CloudWatch Logs 所需的許可。建立角色後，請記下其 Amazon Resource Name (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 函數。使用上一個步驟的角色 ARN 取代 `--role` 的值。此命令會將函式逾時設定為 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. 在文字輸入欄位中輸入角色的名稱，然後選擇 **刪除** 。

**若要刪除 Lambda 函數**

1. 開啟 Lambda 主控台中的 [函數頁面](https://console.aws.amazon.com/lambda/home#/functions)。

1. 選擇您建立的函數。

1. 選擇 **Actions** (動作)、**Delete** (刪除)。

1. 在文字輸入欄位中輸入 **confirm**，然後選擇 **刪除** 。