案例7
题目
某公司构建了一个无服务器应用,使用Amazon API Gateway作为前端入口,触发AWS Lambda函数处理用户请求,并将数据写入Amazon DynamoDB表。用户反馈通过API提交数据时,返回“500 Internal Server Error”,且DynamoDB表中无数据写入。以下是关键配置信息,请排查并解决问题。
相关配置信息
-
API Gateway配置
- 创建了REST API,端点路径为
/submit-data,集成类型为“Lambda代理集成”,目标Lambda函数为data - processor - lambda。 - 启用了AWS_IAM认证,要求调用者携带IAM凭证。
- 创建了REST API,端点路径为
-
Lambda函数配置
- 函数代码(Python):
import boto3 import json dynamodb = boto3.resource('dynamodb') table = dynamodb.Table('user - data - table') def lambda_handler(event, context): data = json.loads(event['body']) table.put_item( Item={ 'UserId': data['userId'], 'Data': data['userData'] } ) return { 'statusCode': 200, 'body': json.dumps('Data stored successfully') } - 执行角色:
lambda - execution - role,策略如下:{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "logs:PutLogEvents", "Resource": "*" } ] }
- 函数代码(Python):
-
DynamoDB表配置
- 表名:
user - data - table,主键为UserId(字符串类型),读写容量模式为按需模式(On - Demand)。 - 表的标签和权限设置均为默认配置(未额外限制)。
- 表名:
解题思路
1. 明确问题范围与可能原因
- 现象:API调用返回500错误,DynamoDB无数据写入,说明Lambda函数执行时发生未处理的异常。
- 可能方向:
- Lambda缺少DynamoDB写入权限(最可能)。
- API Gateway与Lambda集成配置错误。
- 代码逻辑错误(如JSON解析失败、主键缺失)。
- IAM认证配置问题(如API Gateway要求认证但调用方未提供凭证)。
2. 排查Lambda函数的DynamoDB权限
- 核心分析:
Lambda函数需要调用dynamodb:PutItem写入数据,但当前lambda - execution - role的策略仅包含CloudWatch日志权限,完全缺少DynamoDB相关操作权限,这是导致写入失败并触发500错误的直接原因。 - 错误日志线索:
查看Lambda函数的CloudWatch日志,会发现类似以下错误:AccessDeniedException: User: arn:aws:lambda:us-east-1:123456789012:function:data-processor-lambda is not authorized to perform: dynamodb:PutItem on resource: arn:aws:dynamodb:us-east-1:123456789012:table/user-data-table - 修正角色策略:
为lambda - execution - role添加DynamoDB写入权限:{ "Effect": "Allow", "Action": "dynamodb:PutItem", "Resource": "arn:aws:dynamodb:your-region:your-account-id:table/user-data-table" // 替换your-region和your-account-id为实际值 }
3. 检查API Gateway与Lambda的集成配置
- 关键配置点:
- Lambda代理集成:确认API Gateway的集成设置中,“Lambda函数”是否正确关联
data - processor - lambda,且区域一致。 - 请求体处理:Lambda代码中使用
json.loads(event['body'])解析请求体,需确保API Gateway在集成时未修改请求格式(如未启用“二进制数据支持”导致body被编码)。
- 若API Gateway的“二进制媒体类型”未配置,可能导致
event['body']为Base64编码,需添加解码逻辑:import base64 body = base64.b64decode(event['body']).decode('utf-8') data = json.loads(body)
- Lambda代理集成:确认API Gateway的集成设置中,“Lambda函数”是否正确关联
4. 验证代码逻辑与主键约束
- 潜在代码问题:
- 若用户请求体中缺少
userId或userData字段,会导致KeyError或JSON解析失败,需添加异常处理:try: data = json.loads(event['body']) user_id = data['userId'] user_data = data['userData'] except (KeyError, json.JSONDecodeError) as e: return { 'statusCode': 400, 'body': json.dumps(f'Invalid request: {str(e)}') } - 确认DynamoDB表的主键
UserId为字符串类型,且代码中data['userId']确实为字符串(避免类型不匹配错误)。
- 若用户请求体中缺少
5. 排查IAM认证与调用权限
- API Gateway配置:
若启用了AWS_IAM认证,调用API时需携带有效的IAM凭证(如使用AWS SDK或配置了IAM角色的EC2实例)。- 若调用方未提供凭证或权限不足,API Gateway会返回403错误,但本题中是500错误,优先级低于Lambda权限问题。
6. 完整验证步骤
- 修复Lambda角色权限:
- 添加DynamoDB的
PutItem权限到lambda - execution - role。
- 添加DynamoDB的
- 测试API调用:
- 使用Postman或AWS CLI发送POST请求到API Gateway端点,请求体包含正确的
userId和userData:aws apigatewaytest invoke --rest-api-id your-api-id --resource-id your-resource-id --http-method POST --body '{"userId": "123", "userData": "test"}'
- 使用Postman或AWS CLI发送POST请求到API Gateway端点,请求体包含正确的
- 检查日志与表数据:
- Lambda日志:确认无权限错误,且返回200状态码。
- DynamoDB表:查询
UserId为“123”的条目,确认数据已写入。
总结
核心错误:Lambda函数缺少DynamoDB写入权限
- 权限缺失:Lambda执行角色未配置
dynamodb:PutItem,导致写入操作失败并触发内部服务器错误。 - 次要改进:
- 代码中添加输入验证和异常处理,提高鲁棒性。
- 确认API Gateway与Lambda的请求体格式匹配(如处理Base64编码)。
AWS排错核心逻辑:
- 从错误日志定位根源:500错误通常源于后端服务(如Lambda)内部错误,优先检查Lambda日志。
- 权限三要素:
- 调用方(如API Gateway)是否有权限触发Lambda(通过集成配置自动授权,无需额外策略)。
- Lambda执行角色是否有权限操作下游服务(如DynamoDB、S3)。
- 目标服务(如DynamoDB表)是否允许该角色访问(如通过表策略或默认权限)。
通过逐层排查服务间的权限传递和代码逻辑,可快速定位并解决无服务器架构中的典型问题。

浙公网安备 33010602011771号