Lambda集成API Gateway调用SageMaker Endpoint始终返回200状态码问题
问题根源分析
- Lambda响应格式不符合API Gateway代理集成要求:你的代码在正常返回时直接返回SageMaker的
result字典,没有包装成{'statusCode': 200, 'body': json.dumps(result)}的标准格式,API Gateway会默认把Lambda返回的任何非错误结构都视为200响应。 - 错误处理逻辑无效:boto3的
invoke_endpoint在调用SageMaker Endpoint失败时(如过载、超时)会直接抛出异常,不会在返回的response中包含errorMessage,所以你当前判断response.keys()里的errorMessage永远不会触发。 - Lambda超时未正确处理:当Lambda因调用SageMaker超时被runtime终止时,会抛出超时异常,但你的
exception_handler没有返回符合代理集成要求的错误响应,导致API Gateway依旧返回200。
解决方案
1. 统一响应格式
所有返回必须遵循API Gateway代理集成的规范:
- 必须包含
statusCode字段(对应HTTP状态码) body字段必须是JSON字符串(需用json.dumps转换)- 可添加
headers指定响应内容类型
2. 精准捕获SageMaker调用异常
boto3调用SageMaker Endpoint时常见异常包括:
botocore.exceptions.ModelError:模型处理错误(如负载过高导致的推理失败)botocore.exceptions.ClientError:服务端错误(如Endpoint不可用、调用超时)botocore.exceptions.ReadTimeoutError:网络超时
需要针对这些异常返回对应HTTP状态码。
3. 处理Lambda自身超时
在通用异常捕获块中识别超时异常,返回504状态码;其他异常返回502或对应状态码。
修改后的Lambda代码
import json import botocore from aws_lambda_powertools import Logger, Tracer from aws_lambda_powertools.utilities.typing import LambdaContext from aws_lambda_powertools.utilities.correlation_paths import correlation_paths logger = Logger() tracer = Tracer() runtime_client = # 初始化你的boto3 SageMaker runtime客户端 ENDPOINT_NAME = "你的SageMaker端点名称" @logger.inject_lambda_context(correlation_id_path=correlation_paths.API_GATEWAY_REST) @tracer.capture_lambda_handler def lambda_handler(event: dict, context: LambdaContext) -> dict: try: logger.info("Received event", event=event) payload = event['data'] logger.info("Payload to SageMaker", payload=payload) # 调用SageMaker端点 response = runtime_client.invoke_endpoint( EndpointName=ENDPOINT_NAME, ContentType='application/json', Body=json.dumps(payload), Accept='application/json' ) # 解析并返回标准格式响应 result = json.loads(response['Body'].read().decode()) return { 'statusCode': 200, 'body': json.dumps(result), 'headers': {'Content-Type': 'application/json'} } # 捕获SageMaker模型处理错误 except botocore.exceptions.ModelError as e: logger.error("SageMaker Model Error", error=str(e)) return { 'statusCode': 502, 'body': json.dumps({'errorMessage': str(e)}), 'headers': {'Content-Type': 'application/json'} } # 捕获SageMaker服务端错误 except botocore.exceptions.ClientError as e: logger.error("SageMaker Client Error", error=str(e)) error_code = e.response['Error']['Code'] status_code = 504 if error_code == 'TimeoutError' else 502 return { 'statusCode': status_code, 'body': json.dumps({'errorMessage': str(e)}), 'headers': {'Content-Type': 'application/json'} } # 捕获Lambda自身异常(含超时) except Exception as e: logger.error("Lambda Execution Error", error=str(e)) status_code = 504 if "Task timed out" in str(e) else 502 return { 'statusCode': status_code, 'body': json.dumps({'errorMessage': str(e)}), 'headers': {'Content-Type': 'application/json'} }
额外注意事项
- Lambda超时配置:确保Lambda超时时间大于SageMaker Endpoint的预期响应时间,避免Lambda提前终止调用。例如SageMaker最长需10秒响应,Lambda超时设置为15秒。
- SageMaker监控:通过CloudWatch监控
ModelLatency、InvocationErrors等指标,及时发现负载过高情况,考虑扩容端点。 - API Gateway超时:可在API Gateway层面设置超时时间,避免客户端等待过久,但核心还是Lambda返回正确的状态码。
内容的提问来源于stack exchange,提问作者iamabhaykmr
相关产品推荐
相关产品推荐

