如何使用 Lambda 代理集成解决来自 API 网关 REST API 的 HTTP 502 错误?

上次更新时间:2022 年 8 月 8 日

我配置了 Amazon API Gateway 代理集成以用于一个 AWS Lambda 函数。调用我的 REST API 时,我收到一个配置错误和一个 HTTP 502 状态代码。如何解决此问题?

简短描述

如果 Lambda 函数的权限不正确,或者对 API 请求的响应格式不正确,那么 API 网关会返回一个 HTTP 502 状态代码。

Amazon CloudWatch Logs 中出现的 HTTP 502 错误消息示例

Wed Aug 03 08:10:00 UTC 2022 : Execution failed due to configuration error: 
WE Aug 03 09:10:00 UTC 2022 : Method completed with status: 502

– 或者 –

Wed Aug 03 08:20:33 UTC 2022 : Lambda execution failed with status 200 due to customer function error: [Errno 13] Permission denied: '/var/task/lambda_function.py'. Lambda request id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Wed Aug 03 08:20:33 UTC 2022 : Method completed with status: 502

要使 API 网关处理 Lambda 函数的应答,该函数必须按照以下 JSON 格式返回输出:

{
    "isBase64Encoded": true|false,
    "statusCode": httpStatusCode,
    "headers": { "headerName": "headerValue", ... },
    "body": "..."
}

有关更多信息,请参阅用于代理集成的 Lambda 函数的输出格式

解决方案

1.    使用 API Gateway 中的 API 控制面板查看 REST API 的 CloudWatch 指标。
– 或者 –
在 Amazon CloudWatch 控制台中查看您的 REST API 的日志事件

2.    在日志中,查看 Lambda 函数对您的 API 作出的应答格式。如果应答未采用所需的 JSON 格式,请重新格式化它。

3.    验证 Lambda 函数的资源策略是否允许访问通过 API 网关调用该函数。

4.如果由于文件包权限问题,Lambda 函数执行失败,请验证权限。如需获取有关说明,请参阅我在上传 Lambda 部署程序包时遇到 "permission denied" 或 "unable to import module" 错误,如何进行问题排查?

5.    验证 Lambda 函数处理程序名称和配置是否有效

6.    如果 Lambda 在运行时执行失败,请检查 Lambda 函数日志并更新代码。

7.    做出更改后,您可以在 API 网关控制台中测试 REST API 方法

应答格式正确的 Node.js Lambda 示例函数

注意:Node.js Lambda 函数支持异步处理程序非异步处理程序。以下示例函数使用异步处理程序。

exports.handler = async (event) => {

    const responseBody = {
        "key3": "value3",
        "key2": "value2",
        "key1": "value1"
    };

    const response = {
        "statusCode": 200,
        "headers": {
            "my_header": "my_value"
        },
        "body": JSON.stringify(responseBody),
        "isBase64Encoded": false
    };

    return response;
};

在此示例响应中,有四个字段:

  • statusCode 是一个整数,由 API Gateway 解释,返回至 API 方法的发起人。
  • headers 使用 API Gateway 应答采集和发回。
  • 如果要以 JSON 格式返回数据,则必须将 body 转换为字符串。
    注意:您可以在 Node.js 函数中使用 JSON.stringify 来处理此操作。其他运行时需要不同的解决方法,但概念是相同的。
  • 如果正在使用二进制数据,则 isBase64Encoded 是必填字段。如果未使用此字段,最佳实践是将值设置为 FALSE