【问题标题】:502 "Internal Server Error" with API Gateway + Lambda when deploying部署时使用 API Gateway + Lambda 的 502“内部服务器错误”
【发布时间】:2020-04-02 15:13:27
【问题描述】:

我正在使用 API-Gateway + Lambda 组合来处理 POST 请求。我正在使用 Node + Serverless 框架。

当我离线运行无服务器时,我能够发送 POST 请求并将我的数据存储在 S3 上。但是当我部署它并运行相同的 POST 请求时,我会收到“502 内部服务器错误”消息。因为它在本地工作但不能在生产环境中工作,所以我很确定我有一些权限/配置问题。

    saveToS3(newData)
      .then(result => {
        callback(null, {
          statusCode: 200,
          headers: { 'Content-Type': 'application/json' },
          body: "Successfully added data!"
        });
      })
      .catch(e => callback(null, { statusCode: 500, body: JSON.stringify(e) }));

我检查过的内容:

  • 响应正文是一个字符串
  • 在响应中包含状态码、正文、响应标头
  • 使用回调模式返回我的响应(见上文)

没有检查的内容:

  • 一个可能的原因是我的 API-gateway api 无权调用 lambda 函数。如何在 serverless.yml 文件中进行该设置?

我的 yml:

service: myService

provider:
  name: aws
  runtime: nodejs12.x

  iamRoleStatements:
    - Effect: "Allow"
      Action:
        - "s3:GetObject"
        - "s3:PutObject"
      Resource: "arn:aws:s3:::myS3Bucket/*"

functions:
  saveToS3:
    handler: handler.saveToS3
    events:
      - http:
          path: users
          method: post
          cors: true
plugins:
  - serverless-offline

resources:
 Resources:
   NewResource:
     Type: AWS::S3::Bucket
     Properties:
       BucketName: myS3Bucket

【问题讨论】:

  • Serverless Framework 这样创建时会自动赋予API Gateway相关权限。可能值得首先仔细检查明显的事情,例如您是否确实使用 /users 路径调用了正确的 url,并尝试从 API Gateway 控制台运行测试以检查您的 Lambda 响应不是问题。
  • @KMo 很高兴知道,谢谢!

标签: amazon-web-services aws-lambda aws-api-gateway serverless-framework


【解决方案1】:

发现问题,捂脸,因为我花了几个小时才找到它。

我有两个问题:

  • 我的主 lambda 函数前面有一个“异步”,但我是通过回调实现它。删除“异步”修复它。

  • 我的响应格式缺少“标题”和“isBase64Encoded”字段。包括删除 502 错误(见下文)。

有用的链接: - https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-output-format - (如果您使用的是无服务器框架)https://github.com/dherault/serverless-offline/issues/405

如果使用 API 网关,请确保您的 lambda 函数的响应类似于下面的代码 sn-p。否则会抛出“502 - Malformed Lambda Function”错误。

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

【讨论】:

    【解决方案2】:

    如果您使用代理集成,则需要小心,因为对于每个可能的语法错误,它都会引发内部服务器错误。

    catch(e => callback(null, { statusCode: 500, body: JSON.stringify(e) }));
    

    错误可能是这里没有设置标题吗? 如果不是,则可能是语法错误。

    【讨论】:

      【解决方案3】:

      在我们的例子中,我们使用的是无服务器 + API 网关 + Lambda。我们的主要app.ts 导出了一个由无服务器包装的异步处理程序。例如(EnvironmentService 只是环境配置的服务层):

      const allowedBinaryMimeTypes = EnvironmentService.getFileMimeTypesAllowed();
      ...
      const handler = serverless(app, { binary: allowedBinaryMimeTypes });
      

      在修改任何代码之前,502 Bad Gateway 错误日志显示如下 (AWS CloudWatch):

      我们的解决方案是覆盖 serverless.yml 中的默认 aws 提供程序超时:

      S3Service 文件(调用 getObject):

          static async getObject(type: string, pathParams: APIGatewayProxyEventPathParameters): Promise<any> {
              const params = await this.setRequestParams(type, pathParams.id, pathParams.fileName);
      
              try {
                  // get S3 object/file
                  const data = await S3.getObject(params).promise();
      
                  // some bug with AWS converting JPG objects to JPEGg
                  const contentType = data.ContentType === 'image/jpeg' ? 'image/jpg' : data.ContentType;
      
                  return {
                      statusCode: 200,
                      headers: {
                          'Access-Control-Allow-Headers': 'Content-Type',
                          'Access-Control-Allow-Origin': '*', // Required for CORS support to work
                          'Access-Control-Allow-Methods': 'OPTIONS,GET',
                          'Content-Type': contentType
                      },
                      body: data.Body.toString('base64'),
                      isBase64Encoded: true
                  };
              } catch (err) {
                  console.error(err);
                  throw err;
              }
          }
      

      【讨论】:

        猜你喜欢
        • 2019-12-10
        • 2019-12-21
        • 1970-01-01
        • 1970-01-01
        • 2023-02-16
        • 2021-02-04
        • 2019-10-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多