跳至內容

我該如何對 Amazon API Gateway 與 Lambda 函式的整合問題進行疑難排解?

5 分的閱讀內容
0

我想對 Amazon API Gateway 與 Lambda 函式的整合問題進行疑難排解。

解決方法

開啟 API 記錄

請完成以下步驟:

  1. 開啟 API Gateway console (API Gateway 主控台)。
  2. 在導覽窗格中,選擇 APIs,然後選取您的 API。
  3. 在導覽窗格中,選擇 Stages (階段),然後選取您的階段。
  4. Logs and tracing (日誌與追蹤) 下,選擇 Edit (編輯)。
  5. CloudWatch logs (CloudWatch 日誌) 下,從下拉式清單選取一個層級。<br id=hardline_break/> **注意:**若要取得完整的請求與回應日誌,請在記錄層級設為 Error and info logs (錯誤與資訊日誌) 時,選取 Data tracing (資料追蹤) 選項。最佳實務是不為生產 API 開啟 Data tracing (資料追蹤),因為資料追蹤可能會記錄敏感資料。
  6. 選擇 Detailed metrics (詳細指標)。
  7. Custom Access Logging (自訂存取記錄) 下,完成以下步驟:<br id=hardline_break/> 選取 Enable Access Logging (啟用存取記錄)。<br id=hardline_break/>Access Log Destination ARN (存取日誌目的地 ARN),輸入 Amazon Data FirehoseCloudWatch 日誌群組的 Amazon Resource Name (ARN)。<br id=hardline_break/> **注意:**只有 REST API 支援 Firehose ARN。
  8. 輸入日誌格式。
  9. 選擇 Save (儲存)。

判斷整合類型、驗證錯誤,並採取後續步驟進行解決

請完成以下步驟:

  1. 判斷 API Gateway 中是否已設定 Lambda Proxy 整合或 Lambda 自訂整合。若要驗證整合類型,請在 Integration request (整合請求) 下檢查 Lambda proxy integration (Lambda Proxy 整合) 的值。

  2. 驗證 API Gateway 中的錯誤是否與 Lambda 中的錯誤相符。執行以下 CloudWatch Logs Insights 查詢,以在指定時間範圍內找出錯誤狀態碼:

    parse @message '(*) *' as reqId, message
        | filter message like /Method completed with status: \d\d\d/
        | parse message 'Method completed with status: *' as status
        | filter status != 200
        | sort @timestamp asc
        | limit 50
  3. 執行以下 CloudWatch Logs Insights 查詢,以在相同時間範圍內搜尋 Lambda 錯誤日誌:

    fields @timestamp, @message
        | filter @message like /(?i)(Exception|error|fail)/
        | sort @timestamp desc
        | limit 20
  4. 根據您在日誌中識別的錯誤類型,選擇以下其中一項:<br id=hardline_break/> 如果您收到以下錯誤,請完成 Resolve concurrency issues (解決並行問題) 區段中的步驟。

    (#####) Lambda invocation failed with status: 429. Lambda request id: ##########
    () Execution failed due to configuration error: Rate Exceeded.
    (#####) Method completed with status: 500

    如果您收到以下任一錯誤,請完成 Resolve timeout issues (解決逾時問題) 區段中的步驟。<br id=hardline_break/> 若為 Lambda 自訂整合:

    < Integration timeout:
    (#####) Method response body after transformations: {"errorMessage":"2019-08-14T02:45:14.133Z ########-####-####-####-############ Task timed out after ##.01 seconds"}
    > Integration timeout:
    (#####) Execution failed due to a timeout error

    若為 Lambda Proxy 整合:

    < Integration timeout:
    (#####) Endpoint response body before transformations: {"errorMessage":"2019-08-14T02:50:25.865Z ########-####-####-####-############ Task timed out after ##.01 seconds"}
    > Integration timeout:
    (#####) Execution failed due to a timeout error

    如果您收到以下錯誤,請完成 Resolve function errors (解決函式錯誤) 區段中的步驟。

    (#####) Execution failed due to configuration error: Malformed Lambda proxy response
    (#####) Method response body after transformations: {"errorMessage": "Syntax error in module 'lambda_function'"}

解決並行問題

當 API Gateway 傳入的額外請求速度超過 Lambda 函式的擴展速度時,您會收到 429 限流錯誤或 500 錯誤。

若要解決這些錯誤,請分析以下 CloudWatch 指標: 計數 (API Gateway)、限流 (Lambda),以及 ConcurrentExecutions (Lambda)。請考量以下事項:

  • 計數 (API Gateway) 是指定時間範圍內 API 請求的總數。
  • 限流 (Lambda) 是遭到限流的調用請求數量。當所有函式執行個體都在處理請求且沒有可用的並行資源可擴展時,Lambda 會拒絕額外請求並顯示 TooManyRequestsException 錯誤。遭到限流的請求與額外調用錯誤不會計入調用次數或錯誤次數。
  • ConcurrentExecutions (Lambda) 是處理事件的函式執行個體數量。當此數量達到您在 AWS 區域的並行執行配額時,Lambda 會對額外的調用請求進行限流。當函式執行個體數量達到您為該函式設定的保留並行限制時,Lambda 也會對調用請求進行限流。

**注意:**如需更多資訊,請參閱 API Gateway 指標以及 使用 CloudWatch 指標搭配 Lambda

如果您為 Lambda 函式設定了保留並行,請提高保留並行的值。或者,從 Lambda 函式中移除保留並行值。函式接著會從未保留的並行執行集區中取用資源。

如果您未在 Lambda 函式中設定保留並行,請檢查 ConcurrentExecutions 指標以找出使用量。如需更多資訊,請參閱 Lambda 配額

解決逾時問題

所有 API Gateway 整合的預設整合逾時限制為 29 秒。您可以提交配額申請,將區域 API 與私有 API 的預設整合逾時限制配額提高至 29 秒以上。不過,提高整合逾時限制可能需要降低您 AWS 帳戶在該區域層級的限流配額。

**注意:**如果您提高整合逾時限制,請務必將預設的 29 秒逾時值變更為新的值。例如,在您要套用提高後設定的整合中,將預設的 29 秒逾時值變更為新的值。接著,請重新部署 API,讓新的整合逾時限制生效。

當您使用 Lambda 整合來建置 API Gateway API 時,可能會遇到以下其中一種情況:

  • 逾時值小於整合逾時值。
  • 逾時值大於整合逾時值。

如果您的 Lambda 函式逾時時間小於 29 秒,請檢查 Lambda 日誌以調查此問題。如果您的 Lambda 函式必須在 29 秒之後仍持續執行,請以非同步方式調用 Lambda 函式。

針對 Lambda 非同步調用的自訂整合,請完成以下步驟:

  1. 開啟 API Gateway console (API Gateway 主控台)。
  2. 在導覽窗格中,選擇 APIs,然後選擇您的 API。
  3. 選擇 Resources (資源),然後選擇您的方法。
  4. 選擇 Integration Request (整合請求)。
  5. 選擇 Method Request (方法請求)。
  6. 展開 HTTP Request Headers (HTTP 請求標頭)。
  7. 選擇 Add header (新增標頭)。
  8. Name (名稱) 中,輸入您的標頭名稱。例如: X-Amz-Invocation-Type<br id=hardline_break/> **重要:**您必須對應來自 ‘Event’ 的標頭。您必須使用單引號。

針對 Lambda Proxy 整合,請使用兩個 Lambda 函式:函式 A 與函式 B。API Gateway 會先同步調用函式 A。接著,函式 A 會以非同步方式調用函式 B。當函式 A 已非同步調用函式 B 時,函式 A 可以向 API Gateway 傳回成功回應。

如果您使用 Lambda Proxy 整合,則可以將整合變更為自訂整合。不過,若要將請求或回應轉換為您特定的格式,則必須設定對應範本。如需更多資訊,請參閱設定後端 Lambda 函式的非同步調用

**注意:**由於非同步 Lambda 函式會在背景中執行,用戶端無法直接從 Lambda 函式接收資料。您必須使用中介資料庫來儲存任何需要持久保存的資料。

解決函式錯誤

如果您在調用 API 時收到函式錯誤,請檢查 Lambda 函式是否有任何語法錯誤。若 Lambda 函式未傳回 API Gateway 在 Proxy 整合中所預期的有效 JSON 物件,也會出現此錯誤。

您可以從 API Gateway 執行日誌中,查看日誌內的 AWS Integration Endpoint RequestID 值:

(#####) AWS Integration Endpoint RequestId : YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY

接著,您可以執行以下 CloudWatch Logs Insights 查詢,以在相同的特定時間範圍內搜尋 Lambda 日誌:

fields @timestamp, @message, @requestId, @logStream
| filter @requestId = 'YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY'
| sort @timestamp asc

若要解決此錯誤,請完成 Turn on logging for your API and stage (為您的 API 與階段開啟記錄) 一節中的步驟。

覆寫不正確的 REST API 狀態碼回應

如果 API Gateway 傳回不正確的狀態碼,請建立對應範本,將不正確的狀態碼覆寫為正確的狀態碼。您可以在 REST API 的非 Proxy 整合中覆寫狀態碼回應。

**注意:**此對應範本組態只適用於 REST API。若是 HTTP API,請參閱如何在 API Gateway 的 HTTP API 整合中對應回應狀態碼?

例如,如果 API Gateway 傳回 200 狀態碼,而非來自 Lambda 函式的 4## 或 5##,請完成以下步驟:

  1. 開啟 API Gateway console (API Gateway 主控台),並在導覽窗格中選擇 APIs

  2. 選擇您的 REST API,然後選擇 Integration response (整合回應) 索引標籤。

  3. Integration responses settings (整合回應設定) 中,選擇 Edit (編輯)。

  4. 展開 Mapping templates (對應範本),然後選擇 Add mapping template (新增對應範本)。

  5. Content type (內容類型) 中,輸入 application/json

  6. 在對應範本編輯器中,輸入以下程式碼:

    #set($inputRoot = $input.path('$'))
    $input.json("$")
    #if($inputRoot.toString().contains("error"))
    #set($context.responseOverride.status = 400)
    #end
  7. 選擇 Save (儲存)。

$context.responseOverride.status 參數會將狀態碼覆寫為 400,而非整合回應窗格中的預設對應。

如需更多資訊,請參閱在 API Gateway 的 REST API 中覆寫 API 的請求與回應參數及狀態碼

設定 REST API 整合以傳回所需的 CORS 標頭

若要在回應中傳回必要的 CORS 標頭,請設定後端 Lambda 函式HTTP Proxy 伺服器。您必須在 Access-Control-Allow-Origin 標頭值中以清單形式包含允許的網域。

對於 Proxy 整合,您無法在 API Gateway 中設定整合回應來修改 API 後端所傳回的回應參數。在 Proxy 整合中,API Gateway 會將後端回應直接轉送給用戶端。您必須設定 Lambda 函式或 HTTP 整合,以傳回所需的 CORS 標頭。

對於 非 Proxy 整合,您必須手動在 API Gateway 中設定整合回應,以傳回所需的 CORS 標頭。請使用 API Gateway 主控台來設定 CORS。主控台會自動將所需的 CORS 標頭新增至已設定的資源。

如需更多資訊,請參閱如何對 API Gateway API 的 CORS 錯誤進行疑難排解?

二進位承載 Lambda Proxy 整合

二進位承載是指任何非文字的承載。例如,二進位承載可以是 .jpeg 檔案、.gzip 檔案等。這也包含來自 .pdf 應用程式、.jpeg 影像或 .zip 應用程式的一般二進位資料。

若要在 Lambda Proxy 整合中處理二進位承載,您必須對函式回應進行 base64 編碼,並為 API 設定 binaryMediaTypes。若要在非 Proxy 整合中處理二進位承載,您必須將媒體類型新增至 RestApi 資源的 binaryMediaTypes 清單。

如需更多資訊,請參閱 API Gateway 中 REST API 的二進位媒體類型

相關資訊

在 API Gateway 中處理標準 Lambda 錯誤

在 API Gateway 中處理自訂 Lambda 錯誤