

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

# 建置 的自訂執行時間 AWS Lambda
<a name="runtimes-custom"></a>

您可以使用任何程式設計語言實作 AWS Lambda 執行時間。執行時間是一款程式，它會在調用 Lambda 函數時執行該函數的處理常式方法。您可將執行期納入函數的部署套件或是在[層](chapter-layers.md)中分發。建立 Lambda 函數時，選擇[僅限作業系統的執行期](runtimes-provided.md) (`provided` 執行期系列)。

**注意**  
建立自訂執行期是一種進階使用案例。如果您想要了解有關編譯成本機二進位檔或使用第三方現成執行期的資訊，請參閱 [何時使用 Lambda 的僅限作業系統執行時期](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)。
+ **初始化函數** - 載入處理常式檔案並執行其所包含的任何全域或靜態程式碼。函式應只建立一次靜態資源 (如開發套件用戶端和資料庫連線)，以供多次調用時重複使用。
+ **處理錯誤** - 如果發生錯誤，則呼叫[初始化錯誤](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 開發套件使用這個值來連接服務之間的追蹤資料。
+ **建立內容物件** - 建立含有內容資訊的物件，其資訊取自 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` 錯誤。

以下範例 `bootstrap` 檔案使用隨附的 Node.js 版本，在單獨的檔案 `runtime.js` 中執行 JavaScript 執行期。

**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` - 執行期可以使用此端點向 Lambda 報告函數或執行期錯誤，Lambda 也接受 `Transfer-Encoding` 標頭。只能在執行階段開始傳送叫用回應之前呼叫此端點。
+ 在 `/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`請求** – 執行時間可以對[下一個調用](runtimes-api.md#runtimes-api-next) API 進行多個同時呼叫，直到`AWS_LAMBDA_MAX_CONCURRENCY`環境變數指定的限制為止。
+ **處理並行`/response`請求** – 多個調用可以同時呼叫[調用回應](runtimes-api.md#runtimes-api-response) API。
+ **實作執行緒安全請求處理** – 透過正確管理共用資源和狀態，確保並行調用不會互相干擾。
+ **使用唯一的請求 IDs** – 使用 `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)。