Lambda中API调用函数本地正常,部署AWS后无响应排查
AWS Lambda中HTTPS请求仅输出OPTIONS日志后无响应的排查与解决
问题背景
本地VSCode调试以下API调用函数时完全正常,但部署到AWS Lambda后,仅打印OPTIONS日志,后续res/req的回调函数均不执行,也无任何错误抛出。本地与AWS环境的请求配置参数、环境变量完全一致,怀疑是AWS环境限制导致该问题。
const https = require('https'); function CallAPIMethod(method, path, params) { return new Promise((resolve, reject) => { try { console.log("API", `Method ${method}, Path ${path}, Params ${params}`); let responseBody = ''; var options = { host: process.env.API_URL, port: 443, path: `/atservicesrest/v1.0/${path}/${params}`, method: method, headers: { 'Content-Type': 'application/json', 'ApiIntegrationCode': process.env.API_INTEGRATION_CODE, 'UserName': process.env.API_USERNAME, 'Secret': process.env.API_SECRET, 'Accept': "*/*" } }; console.log("OPTIONS", `${JSON.stringify(options)}`); const req = https.request(options, function(res) { console.log('STATUS: ' + res.statusCode); console.log('HEADERS: ' + JSON.stringify(res.headers)); res.setEncoding('utf8'); res.on('data', function(chunk) { console.log('BODY: ' + chunk); responseBody += chunk; // Append the chunk to the responseBody variable }); res.on('end', function() { // The API call has completed, resolve the Promise with the responseBody console.log("RESPONSE", `${responseBody}`); resolve(responseBody); }); }); req.on('error', function(err) { // If there's an error with the API request, reject the Promise with the error console.log("REJECTED", `${err}`); reject(err); }); req.end(); } catch(err) { console.error(`API failed: method ${method}, path ${path}, params ${params}:: Error ${err}`); } }); }
排查与解决步骤
1. 检查Lambda执行超时设置
Lambda默认超时为3秒,如果目标API响应较慢,请求还未完成就会被Lambda强制终止,不会触发任何回调。
- 操作:进入Lambda控制台,找到目标函数,在「配置」>「常规配置」中修改超时时间(建议先设为10秒测试)
- 验证:查看Lambda监控面板的「Duration」指标,确认函数运行时长是否接近超时阈值
2. 排查VPC网络配置
如果Lambda配置了VPC,默认无法直接访问公网(除非子网关联了NAT网关或互联网网关),请求会因无法连接目标API而挂起。
- 操作:
- 若无需VPC:将Lambda函数的VPC配置改为「无」
- 若必须使用VPC:确保Lambda所在子网关联了NAT网关,且安全组的出站规则允许443端口访问目标API的域名/IP范围
3. 验证SSL证书信任问题
Lambda环境的根证书集合可能与本地不同,导致SSL握手卡住,无任何日志输出。
- 测试方案:在
options中临时添加rejectUnauthorized: false(仅用于排查,生产环境禁用),如果请求恢复正常,说明是证书信任问题 - 生产解决:确保目标API使用受公共CA信任的证书,或手动指定CA证书路径
4. 确认环境变量正确性
即使本地参数一致,也要确认Lambda的环境变量是否正确加载:
- 操作:在Lambda控制台查看环境变量,或在函数中添加日志打印
process.env.API_URL、process.env.API_USERNAME等关键变量,确认与本地值完全一致
5. 检查请求路径拼接错误
path拼接逻辑可能导致格式错误,比如params为空时会生成//的无效路径,本地测试时参数有值但Lambda环境下参数为空:
- 操作:添加日志打印完整的
path值,确认格式符合目标API的要求
优化后的代码建议
增加超时处理、完善错误捕获,避免Promise无限挂起:
const https = require('https'); function CallAPIMethod(method, path, params) { return new Promise((resolve, reject) => { try { console.log("API", `Method ${method}, Path ${path}, Params ${params}`); console.log("Env Vars", `API_URL: ${process.env.API_URL}, Username: ${process.env.API_USERNAME}`); let responseBody = ''; const options = { host: process.env.API_URL, port: 443, path: `/atservicesrest/v1.0/${path}/${params}`, method: method, headers: { 'Content-Type': 'application/json', 'ApiIntegrationCode': process.env.API_INTEGRATION_CODE, 'UserName': process.env.API_USERNAME, 'Secret': process.env.API_SECRET, 'Accept': "*/*" }, timeout: 5000 // 设置5秒超时,避免无限挂起 }; console.log("OPTIONS", `${JSON.stringify(options)}`); const req = https.request(options, function(res) { console.log('STATUS: ' + res.statusCode); console.log('HEADERS: ' + JSON.stringify(res.headers)); res.setEncoding('utf8'); res.on('data', function(chunk) { console.log('BODY: ' + chunk); responseBody += chunk; }); res.on('end', function() { console.log("RESPONSE", `${responseBody}`); resolve(responseBody); }); }); // 处理请求超时 req.on('timeout', () => { console.log("REQUEST TIMED OUT"); req.destroy(); reject(new Error('Request timed out')); }); req.on('error', function(err) { console.log("REJECTED", `${err}`); reject(err); }); req.end(); } catch(err) { console.error(`API failed: method ${method}, path ${path}, params ${params}:: Error ${err}`); reject(err); // catch块中主动reject,避免Promise挂起 } }); }
内容的提问来源于stack exchange,提问作者Nick Wright
相关产品推荐
相关产品推荐

