AWS Lambda中foreach循环发送SQS消息表现不一致问题排查
问题排查与修复
核心代码错误:Promise.all 参数嵌套错误
你的两个函数都存在同一个写法问题——给Promise.all传了嵌套数组:
await Promise.all([ products.map(async (product) => { ... }) ])
products.map()返回的本身就是Promise[],你却把它再包进一层数组传给Promise.all。这会导致Promise.all直接把外层数组里的Promise[]当成普通值resolve,根本不会等待内部的异步send操作完成。
为什么restoreCustomers看似正常?大概率是customers数据量小,异步请求在Lambda函数进程销毁前侥幸执行完了;而products数据量更大(你测试用了144条),Lambda进程在send操作完成前就结束了,所以看不到after日志。
而for循环是串行await每个send操作,函数会等待每一步完成,因此能正常运行。
修复后的代码
去掉嵌套的外层数组,直接将map返回的Promise数组传给Promise.all:
const restoreProducts = async (): Promise<void> => { try { // 去掉外层[],直接传入map返回的Promise数组 await Promise.all( products.map(async (product) => { const params: SendMessageCommandInput = { QueueUrl: productSqsUrl, MessageBody: JSON.stringify(product), MessageGroupId: 'PRODUCT', MessageDeduplicationId: product.barcode, } const command = new SendMessageCommand(params) await sqsClient.send(command) return true }) ) } catch (error) { // 添加错误日志,方便排查具体问题 console.error('发送产品消息失败:', error) throw error } }
restoreCustomers也需要做同样修复,否则后续数据量变大时也会出现相同问题。
其他可能的排查点
如果修复后仍有问题,检查以下内容:
- 重复的MessageDeduplicationId:如果
product.barcode存在重复值,FIFO队列会直接丢弃重复ID的消息,甚至抛出错误。可以在send前打印product.barcode确认是否有重复。 - SQS限流:并行发送大量请求可能触发AWS SQS的请求速率限制,可查看CloudWatch中的
NumberOfThrottledRequests指标,或添加重试逻辑。 - Lambda执行超时:若
products数据量极大,并行send的总耗时可能超过Lambda超时时间,需要调整Lambda的超时配置。
内容的提问来源于stack exchange,提问作者CoonHouse
相关产品推荐
相关产品推荐

