返回首頁AWS Lambda

AWS Lambda 錯誤處理完整指南:502、503、504 錯誤解決方案

17 min 分鐘閱讀
#AWS Lambda#錯誤處理#502 Bad Gateway#503 Error#504 Timeout#CloudWatch Logs#X-Ray#DLQ#偵錯#Serverless

AWS Lambda 錯誤處理完整指南:502、503、504 錯誤解決方案

引言:當 Lambda 出錯時

凌晨三點,手機響了。

「API 掛了,全部回傳 502!」

你睡眼惺忪打開筆電,盯著 CloudWatch 的錯誤日誌,完全不知道從何下手。

這個場景太常見了。

Lambda 的錯誤訊息有時候很難解讀。502、503、504 看起來都是「壞掉了」,但原因完全不同。

這篇文章會幫你建立系統性的錯誤排查思維,讓你下次遇到問題時,能在 5 分鐘內定位原因。

如果你還不熟悉 Lambda 的基本概念,建議先閱讀 AWS Lambda 完整指南

插圖 1:Lambda 錯誤監控儀表板

Lambda 錯誤類型概覽

Lambda 的錯誤分為兩大類。

呼叫錯誤 vs 函數錯誤

呼叫錯誤(Invocation Errors):

Lambda 服務層面的問題,函數根本沒開始執行。

常見原因:

  • 並發限制達到上限
  • 權限不足
  • 資源找不到
  • 請求格式錯誤

函數錯誤(Function Errors):

函數開始執行,但過程中出錯。

常見原因:

  • 程式碼語法錯誤
  • 未處理的例外
  • 記憶體不足(OOM)
  • 執行超時

HTTP 狀態碼對應表

當 Lambda 搭配 API Gateway 使用時,錯誤會轉換為 HTTP 狀態碼:

狀態碼錯誤類型常見原因
400請求錯誤請求格式不正確
403權限拒絕API Key 無效、IAM 權限不足
500內部錯誤Lambda 程式碼拋出未處理例外
502Bad GatewayLambda 回應格式錯誤
503Service Unavailable並發限制、服務不可用
504Gateway TimeoutLambda 執行超時

接下來,我們深入分析每個錯誤。


502 Bad Gateway 詳解

502 是最常見的 Lambda 錯誤。

好消息是:它通常很好解決。

常見原因

原因 1:回應格式錯誤(最常見)

API Gateway 期望特定的回應格式。如果 Lambda 回傳的格式不對,就會產生 502。

# 錯誤:直接回傳字串
def lambda_handler(event, context):
    return "Hello World"  # 502!

# 錯誤:body 不是字串
def lambda_handler(event, context):
    return {
        "statusCode": 200,
        "body": {"message": "Hello"}  # body 必須是字串,502!
    }

# 正確格式
def lambda_handler(event, context):
    return {
        "statusCode": 200,
        "headers": {"Content-Type": "application/json"},
        "body": json.dumps({"message": "Hello"})
    }

原因 2:記憶體不足(OOM)

當 Lambda 使用的記憶體超過配置值,會被強制終止。

CloudWatch Logs 中會看到:

Runtime exited with error: signal: killed

原因 3:未處理的例外

程式碼拋出例外但沒有 try-catch,Lambda 會異常終止。

# 這會導致 502
def lambda_handler(event, context):
    data = event["data"]  # 如果 event 沒有 "data" key,會拋出 KeyError
    return {"statusCode": 200, "body": data}

解決方案與程式碼範例

解決方案 1:修正回應格式

建立一個標準的回應函數:

import json

def create_response(status_code, body, headers=None):
    response = {
        "statusCode": status_code,
        "headers": {
            "Content-Type": "application/json",
            "Access-Control-Allow-Origin": "*"
        },
        "body": json.dumps(body) if isinstance(body, dict) else body
    }
    if headers:
        response["headers"].update(headers)
    return response

def lambda_handler(event, context):
    try:
        # 業務邏輯
        result = {"message": "success"}
        return create_response(200, result)
    except Exception as e:
        return create_response(500, {"error": str(e)})

解決方案 2:增加記憶體配置

如果是 OOM 問題:

  1. 前往 Lambda 函數設定
  2. 增加 Memory Size(例如從 128MB 增加到 256MB 或 512MB)
  3. 監控執行記憶體使用量

解決方案 3:完善錯誤處理

def lambda_handler(event, context):
    try:
        # 安全地取得參數
        data = event.get("data", {})
        name = data.get("name", "Unknown")

        # 業務邏輯
        result = process_data(name)

        return create_response(200, result)

    except ValueError as e:
        # 已知的業務錯誤
        return create_response(400, {"error": str(e)})

    except Exception as e:
        # 未預期的錯誤,記錄詳細資訊
        print(f"Unexpected error: {str(e)}")
        return create_response(500, {"error": "Internal server error"})

快速檢查清單

遇到 502 時,按順序檢查:

  • 回應格式是否正確?(statusCode + body 字串)
  • CloudWatch Logs 是否有 "signal: killed"?(OOM)
  • 是否有未處理的例外?(檢查日誌的錯誤訊息)
  • body 是否為字串?(不能是 dict 或 list)

更多 API Gateway 整合細節,請參考 Lambda + API Gateway 整合教學


錯誤一直排不掉?預約免費諮詢,讓專家幫你診斷問題。


503 Service Unavailable 詳解

503 表示 Lambda 服務暫時無法處理請求。

常見原因

原因 1:並發執行限制達到上限

Lambda 帳戶預設有 1,000 個並發執行限制(可申請提高)。

當所有並發都被佔用,新請求會收到 503。

原因 2:Reserved Concurrency 設定過低

如果你為特定函數設定了 Reserved Concurrency,超過這個值的請求會被拒絕。

例如:設定 Reserved Concurrency = 10,同時來 15 個請求,有 5 個會收到 503。

原因 3:Provisioned Concurrency 配置問題

使用 Provisioned Concurrency 時,如果配置的數量不足以處理流量峰值,超出的請求可能會被節流。

解決方案

解決方案 1:申請提高並發限制

  1. 前往 AWS Service Quotas
  2. 搜尋「Lambda concurrent executions」
  3. 申請提高配額(通常需要 1-3 個工作天)

解決方案 2:調整 Reserved Concurrency

評估函數的實際需求,調整合適的 Reserved Concurrency 值。

或者移除 Reserved Concurrency 限制,讓函數共用帳戶配額。

解決方案 3:實作重試機制

對於可接受短暫延遲的場景,在客戶端實作指數退避重試:

import time
import requests

def call_api_with_retry(url, max_retries=3):
    for attempt in range(max_retries):
        try:
            response = requests.get(url)
            if response.status_code == 503:
                wait_time = (2 ** attempt) + random.random()
                print(f"503 error, retrying in {wait_time:.2f}s...")
                time.sleep(wait_time)
                continue
            return response
        except Exception as e:
            if attempt == max_retries - 1:
                raise
    raise Exception("Max retries exceeded")

解決方案 4:使用 SQS 緩衝

將請求放入 SQS 佇列,由 Lambda 以穩定的速率處理:

Client → SQS Queue → Lambda (batch processing)

這樣可以避免突發流量導致的節流問題。

想了解 Provisioned Concurrency 的費用影響,請參考 AWS Lambda 費用計算完整指南

插圖 2:Lambda 並發限制與節流示意圖

504 Gateway Timeout 詳解

504 表示 Lambda 執行時間超過了 API Gateway 的限制。

常見原因

原因 1:Lambda 執行超時

Lambda 本身有 15 分鐘的執行上限。

但搭配 API Gateway 時,限制更嚴格:

  • REST API:29 秒
  • HTTP API:30 秒

超過這個時間,API Gateway 會回傳 504。

原因 2:外部 API 延遲

Lambda 呼叫外部服務(資料庫、第三方 API)太慢:

# 如果這個請求花了 35 秒,就會超時
response = requests.get("https://slow-external-api.com/data")

原因 3:Cold Start + 處理時間

Cold Start 可能花費 1-10 秒(視語言和套件大小),加上正常處理時間,可能超過 30 秒限制。

解決方案

解決方案 1:優化程式碼執行時間

  • 減少不必要的計算
  • 平行處理獨立任務
  • 使用更高效的演算法
import asyncio
import aiohttp

async def fetch_all(urls):
    async with aiohttp.ClientSession() as session:
        tasks = [fetch_one(session, url) for url in urls]
        return await asyncio.gather(*tasks)

# 平行呼叫多個 API,而不是逐一呼叫
results = asyncio.run(fetch_all(urls))

解決方案 2:增加 Lambda Timeout 設定

在 Lambda 設定中調整 Timeout:

  1. 前往函數設定
  2. 一般組態 → 逾時
  3. 設定適當的值(最高 15 分鐘)

注意:這無法解決 API Gateway 的 30 秒限制。

解決方案 3:改用非同步處理

對於長時間任務,改用非同步模式:

1. Client 發送請求
2. Lambda 將任務放入 SQS/EventBridge
3. 立即回傳 202 Accepted + 任務 ID
4. 背景 Lambda 處理任務
5. Client 輪詢結果或透過 WebSocket 接收通知

想了解更多非同步處理架構,請參考 Lambda + EventBridge 事件驅動架構實戰

解決方案 4:使用 Provisioned Concurrency 減少 Cold Start

# 啟用 Provisioned Concurrency
# 1. 發布 Lambda 版本
# 2. 為該版本設定 Provisioned Concurrency
# 這可以消除 Cold Start,但有額外費用

Timeout 問題很難根治? 這通常是架構設計問題,不只是調參數那麼簡單。

預約架構諮詢,讓我們幫你重新設計流程。


偵錯工具與技巧

有了正確的工具,偵錯會容易很多。

CloudWatch Logs 查看方法

每個 Lambda 執行都會自動記錄到 CloudWatch Logs。

找到日誌:

  1. 前往 CloudWatch → Log groups
  2. 搜尋 /aws/lambda/函數名稱
  3. 選擇最近的 Log stream

關鍵日誌訊息:

# 正常執行
START RequestId: xxx
... 你的 print 輸出 ...
END RequestId: xxx
REPORT RequestId: xxx Duration: 123.45 ms Billed Duration: 124 ms Memory Size: 128 MB Max Memory Used: 64 MB

# OOM 錯誤
Runtime exited with error: signal: killed

# 程式碼錯誤
[ERROR] KeyError: 'data'
Traceback (most recent call last):
  File "/var/task/lambda_function.py", line 5, in lambda_handler
    data = event["data"]

使用 Log Insights 查詢:

# 找出所有錯誤
fields @timestamp, @message
| filter @message like /ERROR/
| sort @timestamp desc
| limit 20

# 找出執行時間最長的請求
fields @timestamp, @duration
| sort @duration desc
| limit 10

X-Ray 追蹤請求

X-Ray 可以追蹤請求的完整路徑,找出效能瓶頸。

啟用 X-Ray:

  1. 前往 Lambda 函數設定
  2. 監控和操作工具 → 啟用「主動追蹤」

在程式碼中加入追蹤:

from aws_xray_sdk.core import xray_recorder
from aws_xray_sdk.core import patch_all

# 自動追蹤 HTTP 請求、資料庫呼叫等
patch_all()

@xray_recorder.capture('process_data')
def process_data(data):
    # 這個函數的執行時間會被追蹤
    return transformed_data

查看追蹤結果:

  1. 前往 X-Ray → Traces
  2. 查看服務地圖,找出慢的節點
  3. 點擊個別請求查看詳細時間分布

本地測試(SAM Local)

在部署前先在本地測試,可以更快發現問題。

安裝 SAM CLI:

# macOS
brew install aws-sam-cli

# Windows
msi installer from AWS

# 驗證安裝
sam --version

本地執行 Lambda:

# 建立測試事件
echo '{"name": "test"}' > event.json

# 本地執行函數
sam local invoke MyFunction --event event.json

# 啟動本地 API
sam local start-api

這樣可以在部署前捕捉大部分錯誤。

插圖 3:X-Ray 服務追蹤地圖

錯誤處理最佳實踐

除了解決當前錯誤,更重要的是建立防護機制。

結構化錯誤回應

統一的錯誤回應格式,讓前端更容易處理:

def create_error_response(status_code, error_code, message, details=None):
    body = {
        "error": {
            "code": error_code,
            "message": message
        }
    }
    if details:
        body["error"]["details"] = details

    return {
        "statusCode": status_code,
        "headers": {"Content-Type": "application/json"},
        "body": json.dumps(body)
    }

# 使用範例
return create_error_response(
    400,
    "INVALID_INPUT",
    "Name is required",
    {"field": "name"}
)

DLQ 設定

Dead Letter Queue(DLQ)可以捕捉處理失敗的事件,避免資料遺失。

設定步驟:

  1. 建立 SQS Queue 作為 DLQ
  2. 前往 Lambda 函數設定
  3. 非同步呼叫 → 目的地
  4. 失敗時:選擇 SQS Queue

處理 DLQ 訊息:

# 另一個 Lambda 處理 DLQ 訊息
def dlq_handler(event, context):
    for record in event['Records']:
        # 記錄失敗的事件
        failed_event = json.loads(record['body'])
        print(f"Processing failed event: {failed_event}")

        # 可以發送通知、儲存到資料庫等
        notify_team(failed_event)

監控與警示

如果你使用 Terraform 管理 Lambda,可以將這些錯誤處理設定納入 Infrastructure as Code,請參考 Terraform 部署 Lambda 教學

設定 CloudWatch Alarms 在問題發生時即時通知:

關鍵指標:

  • Errors:函數錯誤次數
  • Throttles:被節流的請求
  • Duration:執行時間
  • ConcurrentExecutions:並發執行數

設定警示:

# 使用 CloudFormation/SAM 設定
ErrorAlarm:
  Type: AWS::CloudWatch::Alarm
  Properties:
    AlarmName: LambdaHighErrorRate
    MetricName: Errors
    Namespace: AWS/Lambda
    Dimensions:
      - Name: FunctionName
        Value: !Ref MyFunction
    Statistic: Sum
    Period: 60
    EvaluationPeriods: 1
    Threshold: 5
    ComparisonOperator: GreaterThanThreshold
    AlarmActions:
      - !Ref AlertTopic

常見問題 FAQ

502 和 500 錯誤有什麼差別?

500 錯誤通常是 Lambda 程式碼拋出例外但有被 API Gateway 正確接收;502 是 Lambda 回應格式錯誤或異常終止,API Gateway 無法解析回應。修正 502 通常需要檢查回應格式和記憶體配置。

如何查看 Lambda 的詳細錯誤日誌?

前往 CloudWatch Logs,搜尋 /aws/lambda/函數名稱 的 Log group。日誌會顯示完整的錯誤訊息和堆疊追蹤。也可以使用 Log Insights 進行更複雜的查詢分析。

Lambda Timeout 最長可以設多久?

Lambda 本身最長可設定 15 分鐘(900 秒)。但搭配 API Gateway 時,REST API 限制 29 秒,HTTP API 限制 30 秒。超過這個時間的任務應改用非同步處理。

如何避免 Cold Start 導致的超時?

使用 Provisioned Concurrency 可以消除 Cold Start。或者優化程式碼套件大小、選擇 Cold Start 較快的語言(Python、Node.js),以及將初始化邏輯移到 Handler 外部只執行一次。


結語:建立穩健的錯誤處理機制

錯誤是無法完全避免的。

重要的是建立完善的偵測和處理機制,讓錯誤發生時能夠快速發現、快速修復。

關鍵要點回顧:

錯誤碼主要原因首要檢查
502回應格式錯誤return 格式、OOM
503並發限制帳戶配額、Reserved Concurrency
504執行超時API Gateway 30 秒限制

下一步建議:

  1. 為所有 Lambda 函數設定統一的錯誤處理模式
  2. 設定 CloudWatch Alarms 監控關鍵指標
  3. 為關鍵函數配置 DLQ 避免資料遺失
  4. 定期檢視錯誤日誌,找出潛在問題

Lambda 問題需要專家協助?

如果你正在:

  • 處理反覆出現的 Lambda 錯誤
  • 優化 Lambda 的執行效能
  • 設計更穩定的 Serverless 架構

預約架構諮詢,我們會在 24 小時內回覆你。

正確的架構設計能避免 90% 的執行階段錯誤。


參考資料

  1. AWS 官方文件:Lambda Error Handling
  2. AWS 官方文件:Troubleshooting Lambda
  3. AWS 官方文件:CloudWatch Logs Insights
  4. AWS 官方文件:X-Ray for Lambda
  5. AWS Blog:Error handling patterns in Amazon API Gateway and AWS Lambda

需要專業的雲端建議?

無論您正在評估雲平台、優化現有架構,或尋找節費方案,我們都能提供協助

預約免費諮詢

相關文章