You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS Lambda测试正常但Postman/请求返回空白响应问题

AWS Lambda通过API Gateway返回空响应问题排查与解决

问题背景

我使用AWS Lambda搭建前后端中间服务,核心逻辑:

  • 接收前端传来的payload并转发至后端服务
  • 后端正常运行时,返回200状态码及机器学习模型进度数据(短轮询)
  • 后端未启动或Pod重启时,返回存储在S3response.json中的历史数据,直到后端恢复

Lambda在控制台测试时功能正常,但通过Postman或Python脚本调用API Gateway触发Lambda时,虽返回200状态码,但响应体为空。

相关代码与测试信息

Lambda函数代码

import json
import os
import requests
import boto3

# Initialize the S3 client
s3 = boto3.client('s3')

def save_json_file_to_s3(response_payload, filename="response.json"):
    bucket_name = 'mys3store'
    s3.put_object(Bucket=bucket_name, Key=filename, Body=json.dumps(response_payload))

def read_json_file_from_s3(filename="response.json"):
    bucket_name = 'mys3store'
    response = s3.get_object(Bucket=bucket_name, Key=filename)
    content = response['Body'].read().decode('utf-8')
    response_payload= json.loads(content)
    return response_payload

def lambda_handler(event, context):
    """Forwards a POST request to another service and redirects back to the first microservice."""
    
    print(event)
    print(type(event))
    print("=========================================================")

    # Get the request data from the event.
    try:
        request_data = json.loads(event["body"])
    except KeyError as e:
        request_data = event

    # Get the destination URL from the request data.
    dest_url = request_data["dest_url"]

    # Forward the POST request to the destination service.
    response = requests.post(dest_url, json=request_data)

    # Check the response status code.
    if response.status_code == 200:
        response_payload = json.loads(response.content)
        print("++++++++++++++++++++++++++++++++++")
        print(response_payload)
        print("++++++++++++++++++++++++++++++++++")
        save_json_file_to_s3(response_payload)
        return {
            "statusCode": 200,
            "body": json.dumps(response_payload),
            "headers": {"Content-Type": "application/json"}
        }
    elif response.status_code == 502:
        response_payload = read_json_file_from_s3()
        return {
            "statusCode": 200,
            "body": json.dumps(response_payload),
            "headers": {"Content-Type": "application/json"}
        }
    else:
        return {
            "statusCode": 500,
            "body": json.dumps({"error": "Unexpected response from destination service."}),
            "headers": {"Content-Type": "application/json"}
        }

控制台测试事件

{
  "app": "my_app",
  "session_id": "3432428374827347234",
  "table": "progress",
  "user_id": "myaccount@gmail.cm",
  "flag": false,
  "project_name": "mybig1gbproject",
  "user_name": "john doe",
  "file_name": "",
  "fit_progress": 0,
  "model_fit": 0,
  "total_fit": 0,
  "model_calc": 0,
  "total_calc": 0,
  "calc_progress": 0,
  "model_arch": "lambda",
  "dest_url": "https://mybackendservice/api/maincore/progress"
}

控制台测试结果(正常)

Test Event Name
checkLiveOrNot

Response
{
  "statusCode": 200,
  "body": "{\"_id\": \"34347tyi738483h8d73h\", \"session_id\": \"3432428374827347234\", \"data\": 0, \"model_no\": 0, \"table\": \"progress\", \"total_fit\": 1, \"total_calc\": 1, \"orc_fail\": 0, \"model_progress\": 0.0, \"current_model\": 0, \"model_progress\": 100.0, \"current_calc\": 1}",
  "headers": {
    "Content-Type": "application/json"
  }
}

Function Logs
START RequestId: 0d820ce34rtry9-2e11-420dsdfa-961e-c4434515b18f Version: $LATEST
{'app': 'my-app', 'session_id': '34347tyi738483h8d73h', 'table': 'progress', 'user_id': 'danish.xavier@iqvia.com', 's3_flag': False, 'project_name': 'checksampleforapitesting', 'user_name': 'danish.xavier', 'file_name': '', 'model_fit_progress': 0, 'current_model_fit': 0, 'total_model_fit': 0, 'current_model_calc': 0, 'total_model_calc': 0, 'model_calc_progress': 0, 'model_arch': 'eks', 'dest_url': 'https://promo-internal-promo-usv-demotemp-env.mmx.mco.solutions.iqvia.com/api/core/progress_lambda'}
<class 'dict'>
=========================================================
++++++++++++++++++++++++++++++++++
{'_id': '34347tyi738483h8d73h', 'session_id': '34347tyi738483h8d73h', 'data': 0, 'model_no': 0, 'table': 'progress', 'total_fit': 1, 'total_calc': 1, 'orc_fail': 0, 'model_progress': 0.0, 'current_model': 0, 'model_progress': 100.0, 'current_calc': 1}
++++++++++++++++++++++++++++++++++
END RequestId: 0d820ce9-2e11-420a-961e-c4434515b18f
REPORT RequestId: 0d82dfdf0ce9-2dfdfe11-42dfdf0a-961e-c44345dfdf15b18f  Duration: 281.79 ms Billed Duration: 282 ms Memory Size: 128 MB Max Memory Used: 54 MB  Init Duration: 324.60 ms

Postman/Python脚本调用问题

使用Python脚本调用API Gateway时,返回200但响应体为空:

import json
import requests

headers = {'Content-Type': 'application/json'}

payload = {
  "app": "my_app",
  "session_id": "3432428374827347234",
  "table": "progress",
  "user_id": "myaccount@gmail.cm",
  "flag": False,  # 注意:原脚本中false是Python语法错误,需改为False
  "project_name": "mybig1gbproject",
  "user_name": "john doe",
  "file_name": "",
  "fit_progress": 0,
  "model_fit": 0,
  "total_fit": 0,
  "model_calc": 0,
  "total_calc": 0,
  "calc_progress": 0,
  "model_arch": "lambda",
  "dest_url": "https://mybackendservice/api/maincore/progress"
}

response = requests.post(
    'https://8973043wa7lrta.execute-api.us-east-1.amazonaws.com/dev/progress_lambda',
    headers=headers,
    json=payload
)

if response.status_code == 200:
    print('Request successful')
    print(response.content)

脚本输出:

Request successful
b''

问题排查与解决方法

1. 检查API Gateway集成模式

如果API Gateway未配置Lambda代理集成,Lambda返回的statusCode/body/headers格式无法被正确解析,导致响应体为空。

  • 操作步骤:
    1. 进入AWS API Gateway控制台,找到对应的API和POST方法
    2. 在"集成请求"中,确认"集成类型"为"Lambda函数",并勾选"使用Lambda代理集成"
    3. 保存配置后,重新部署API到对应阶段

2. 为后端请求添加异常捕获

当前代码中requests.post未处理异常,若后端服务连接失败、超时或返回非预期状态,会导致Lambda抛出未捕获异常,API Gateway返回空响应。

  • 修改代码:在转发请求部分添加异常处理逻辑
# Forward the POST request to the destination service.
try:
    response = requests.post(dest_url, json=request_data, timeout=10)
    response.raise_for_status()  # 触发HTTP状态码异常(如4xx/5xx)
except requests.exceptions.RequestException as e:
    print(f"请求后端服务失败: {str(e)}")
    # 尝试读取历史数据返回
    try:
        response_payload = read_json_file_from_s3()
        return {
            "statusCode": 200,
            "body": json.dumps(response_payload),
            "headers": {"Content-Type": "application/json"}
        }
    except Exception as s3_err:
        return {
            "statusCode": 500,
            "body": json.dumps({"error": f"后端服务不可用且无法读取历史数据: {str(s3_err)}"}),
            "headers": {"Content-Type": "application/json"}
        }

3. 验证Lambda执行角色权限

控制台测试使用的是测试角色,而API Gateway调用使用Lambda的执行角色,需确保执行角色拥有S3桶mys3store的读写权限:

  • 操作步骤:
    1. 进入IAM控制台,找到Lambda的执行角色
    2. 添加自定义策略,允许对s3://mys3store/response.json执行s3:GetObject和s3:PutObject操作

4. 查看CloudWatch日志定位问题

通过CloudWatch查看API Gateway调用时的Lambda日志,确认:

  • event结构是否正确(API Gateway触发的event包含body字段,值为JSON字符串)
  • request_data是否正确解析
  • 请求后端服务的响应状态码及内容
  • 是否有未捕获的异常信息

内容的提问来源于stack exchange,提问作者Danish Xavier

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 12:37:03