AWS Lambda中MongoClient连接Atlas失败未触发catch块原因排查
问题:MongoDB Atlas连接失败未触发catch块,Lambda任务超时
我用Node.js编写了连接MongoDB Atlas的AWS Lambda函数,代码如下:
try { if (!conn) { console.log("Attempting to Connect to Atlas"); conn = await MongoClient.connect(process.env.MONGO_URL, { useNewUrlParser: true, useUnifiedTopology: true, }); console.log("Successfully connected to Atlas"); } } catch (err) { console.log("Failed to connect to Atlas: ", err); return { statusCode: 500, body: JSON.stringify(err), }; }
由于Atlas数据库未将Lambda所在服务器IP加入白名单,连接理应失败,但实际未执行catch块代码,日志显示任务超时:
2022-11-28T14:10:35.966-06:00 2022-11-28T20:10:35.966Z 7e455355-8126-4f71-afb3-2185683f9f8a INFO Attempting to Connect to Atlas 2022-11-28T14:10:38.725-06:00 2022-11-28T20:10:38.725Z 7e455355-8126-4f71-afb3-2185683f9f8a Task timed out after 3.01 seconds 2022-11-28T14:10:38.725-06:00 END RequestId: 7e455355-8126-4f71-afb3-2185683f9f8a 2022-11-28T14:10:38.725-06:00 REPORT RequestId: 7e455355-8126-4f71-afb3-2185683f9f8a Duration: 3008.53 ms Billed Duration: 3000 ms Memory Size: 128 MB Max Memory Used: 49 MB 2022-11-28T14:11:42.725-06:00 START RequestId: 7e455355-8126-4f71-afb3-2185683f9f8a Version: $LATEST
请问为何连接失败时未抛出错误、未进入catch块?
原因分析与解决方案
核心原因
- MongoDB驱动默认超时过长:MongoClient.connect的默认连接/服务器选择超时通常远大于你设置的Lambda 3秒超时。当IP不在白名单时,Atlas会静默拒绝连接,驱动会一直重试直到自身超时,但Lambda在驱动抛出错误前就先触发了任务超时,导致catch块根本没机会执行。
- Lambda超时时间过短:你的Lambda超时设为3秒,比MongoDB驱动的默认超时短太多,Lambda先挂了,驱动还没来得及抛出连接错误。
解决办法
- 给MongoDB连接设置更短的超时
在connect配置中添加serverSelectionTimeoutMS和connectTimeoutMS,设置成小于Lambda超时的数值(比如2秒),确保驱动能在Lambda超时前抛出错误进入catch块。修改后的代码:
try { if (!conn) { console.log("Attempting to Connect to Atlas"); conn = await MongoClient.connect(process.env.MONGO_URL, { useNewUrlParser: true, useUnifiedTopology: true, serverSelectionTimeoutMS: 2000, // 服务器选择超时,单位毫秒 connectTimeoutMS: 2000 // 连接超时,单位毫秒 }); console.log("Successfully connected to Atlas"); } } catch (err) { console.log("Failed to connect to Atlas: ", err); return { statusCode: 500, body: JSON.stringify(err), }; }
- 调整Lambda超时时间(可选)
如果需要更长的连接等待时间,可以适当提高Lambda的超时时间,但必须保证MongoDB的超时设置小于Lambda的超时时间,这样错误才能被catch到。不过更推荐缩短MongoDB的超时,避免Lambda长时间空等。
内容的提问来源于stack exchange,提问作者Bear Bile Farming is Torture
相关产品推荐
相关产品推荐

