AWS Lambda并发升至15后停止执行handler代码求助排查
问题背景
我有一个超时时间为900秒(15分钟)的AWS Lambda函数,原本通过EventBridge每20分钟调度一次,代码内置运行至14分钟自动结束的逻辑,运行状态正常。
调整配置后出现异常:
- 将函数预留并发限制设为15
- EventBridge调度改为每分钟一次
异常表现:
- 函数每分钟触发一次,当并发执行数达到15后,
lambda_handler内的代码停止执行 - 并发数从15降至1,单次执行耗时仅1.74ms
lambda_handler下的print语句未执行,仅触发函数调用但未运行内部代码- 重新部署函数后恢复正常,说明冷启动正常但暖实例存在异常
- 已启用X-Ray,但仅显示执行耗时2ms
更新1:Lambda函数代码
注:隐藏了process_symbol()的实现,该函数仅用于下载股票代码数据并保存至S3。
import os import json import s3fs import urllib3 from datetime import datetime MAX_RUNNING_TIME_SECONDS = 900 # Timing start_execution_time = datetime.now() def get_execution_time_remaining(): return MAX_RUNNING_TIME_SECONDS - (datetime.now() - start_execution_time).seconds def lambda_handler(event, context): print('Execution beginning') symbols = [] execution_time_remaining = get_execution_time_remaining() while execution_time_remaining > 60: # Get next symbol to load symbol_metadata = get_next_symbol_to_load() if symbol_metadata: symbol = symbol_metadata[0] symbols.append(symbol) # process_symbol(symbol) # update_rds(symbol) execution_time_remaining = get_execution_time_remaining() print(f'execution_time_remaining = {execution_time_remaining}') return_message = '' current_time_text = datetime.now().strftime('%m/%d/%Y, %H:%M:%S.%f') if symbols: return_message = f"Successfully saved {', '.join(symbols)} to the cloud at {current_time_text}." else: return_message = f'Successfully execution at {current_time_text} but no symbols were processed.' return { "statusCode": 200, "body": return_message, }
更新2
当并发数升至15并停止执行函数代码后,约80-90分钟后会自行恢复执行代码。
排查方向及解决思路
1. 全局变量初始化问题
代码中start_execution_time是全局变量,仅在Lambda冷启动时赋值,暖实例复用该变量。首次调用后,后续调用的get_execution_time_remaining()会基于冷启动时间计算剩余时间,直接得到负数,导致while循环不执行,直接进入返回逻辑,表现为耗时极短且无业务代码执行。
- 解决思路:将
start_execution_time移至lambda_handler内部,每次调用重新初始化:def lambda_handler(event, context): start_execution_time = datetime.now() print('Execution beginning') # 后续逻辑使用该局部变量计算剩余时间
2. 预留并发实例生命周期排查
预留并发实例被标记为异常后,AWS Lambda会在一段时间后回收重建。当15个预留实例全部因全局变量问题进入异常状态后,新请求无法分配到正常实例,直到异常实例被回收,新冷启动实例接管请求,这与80-90分钟后自行恢复的现象匹配。
- 排查动作:在CloudWatch Logs中按实例ID分组,确认是否同一批实例持续出现异常,直到一段时间后切换为新实例ID。
3. CloudWatch Logs深度分析
X-Ray仅记录整体耗时,但CloudWatch Logs可能包含实例初始化错误、全局变量引发的隐性异常(如时间计算逻辑错误)。
- 排查动作:
- 筛选异常时间段的日志,按实例ID分组查看
- 检查是否存在未捕获的异常日志(比如
get_next_symbol_to_load()中的错误导致代码提前退出但未抛出异常)
4. 执行上下文复用副作用排查
Lambda暖实例会复用执行上下文,全局变量、模块级初始化代码仅执行一次。除时间变量外,s3fs、urllib3等模块的连接池或状态可能在多次调用后异常,导致代码无法执行。
- 排查方向:将客户端初始化(如
s3fs.S3FileSystem())移至lambda_handler内部,或在每次调用时重置模块状态。
5. 并发调度与运行时长冲突验证
原函数单次运行最长14分钟,调整为每分钟调度后,预留并发15刚好支撑前15次调用(每个实例处理一次14分钟任务),但后续请求分配到暖实例时,因全局变量问题直接返回,表现为无代码执行。
- 验证思路:测试单实例多次调用,观察是否首次调用正常,后续调用出现异常。
内容的提问来源于stack exchange,提问作者Jonathan Garvey

