Node.js Serverless Offline首次请求后无响应问题排查
问题分析与解决方案
这问题我太熟了!核心坑点就在你用的db.once('open', ...)上,咱们一步步理清楚:
第一次请求时,数据库连接还没建立,db.once('open')会正常触发回调,Client.findOne能顺利执行并调用callback,所以功能正常。但第二次请求时,数据库连接已经处于打开状态了——once这个方法只会触发一次,后续再触发open事件它根本不搭理!这就导致里面的查询逻辑完全没机会跑,Lambda一直等着callback被调用,最后只能超时返回Promise错误。
修复方案
方案1:替换once为on(快速临时修复)
把db.once改成db.on,这样每次连接打开时都会触发回调。不过这个方案有点冗余,因为数据库连接建立后不会频繁断开重连,但能快速解决问题:
module.exports.getOne = (event, context, callback) => { context.callbackWaitsForEmptyEventLoop = false; db.on('open', () => { Client.findOne({name:{ $regex : new RegExp(event.pathParameters.name, "i") }}) .then(client => callback(null, { statusCode: 200, body: JSON.stringify(client) })) .catch(err => { console.error('查询出错:', err); callback(err, { statusCode: 500, body: JSON.stringify({ error: '查询失败' }) }); }); }); };
方案2:提前初始化数据库连接(推荐最佳实践)
更好的做法是在Lambda模块外部提前完成数据库连接初始化,后续请求直接复用已有的连接,不用每次都监听连接事件:
// 在模块顶部提前初始化数据库连接 db.connect() .then(() => console.log('数据库连接成功建立')) .catch(err => console.error('数据库连接失败:', err)); module.exports.getOne = (event, context, callback) => { context.callbackWaitsForEmptyEventLoop = false; // 直接执行查询,连接已经就绪 Client.findOne({name:{ $regex : new RegExp(event.pathParameters.name, "i") }}) .then(client => callback(null, { statusCode: 200, body: JSON.stringify(client) })) .catch(err => { console.error('查询出错:', err); callback(err, { statusCode: 500, body: JSON.stringify({ error: '查询失败' }) }); }); };
这样不管是第一次还是后续请求,都能直接执行查询逻辑,彻底避免连接事件不触发导致的超时问题。
额外重要提醒
千万别漏掉catch块处理Promise错误!如果查询过程中抛出异常但没被捕获,同样会导致Lambda一直等待callback调用,最终超时。
内容的提问来源于stack exchange,提问作者Hareesh
相关产品推荐
相关产品推荐

