Node.js应用部署Azure App Service后,重启时Azure Cosmos DB for MongoDB连接超时
问题:Azure App Service重启后Node.js应用连接Cosmos DB for MongoDB超时
我有一个Node.js应用,使用Azure Cosmos DB for MongoDB作为数据库,部署在Azure App Service上。应用刚部署完成后运行正常,但重启App Service时,数据库重连会触发超时错误。
连接脚本
const { MongoClient } = require('mongodb'); module.exports = { client: client = new MongoClient(process.env.MONGODB_URI), connectToDB: async () => { try { await client.connect(); console.log('connected!') } catch (err) { console.log('Err', err) } } }
连接超时错误信息
Err MongoServerSelectionError: connection timed out at Timeout._onTimeout (C:\home\site\wwwroot\node_modules\mongodb\lib\sdam\topology.js:292:38) at listOnTimeout (internal/timers.js:554:17) at processTimers (internal/timers.js:497:7) { reason: TopologyDescription { type: 'Single', servers: Map { 'xxx.mongo.cosmos.azure.com:10255' => [ServerDescription] }, stale: false, compatible: true, heartbeatFrequencyMS: 10000, localThresholdMS: 15, setName: 'globaldb', maxElectionId: null, maxSetVersion: null, commonWireVersion: 0, logicalSessionTimeoutMinutes: null }, code: undefined, [Symbol(errorLabels)]: Set {} }
解决方案
1. 调整MongoClient连接参数
Cosmos DB在服务重启后可能需要更长时间响应连接请求,给MongoClient添加超时和重试相关配置:
const { MongoClient } = require('mongodb'); module.exports = { client: new MongoClient(process.env.MONGODB_URI, { connectTimeoutMS: 30000, // 延长连接超时到30秒 socketTimeoutMS: 45000, // 延长Socket超时到45秒 retryWrites: true, // 开启写入重试 maxPoolSize: 10 // 根据应用规模调整连接池大小 }), connectToDB: async () => { try { await client.connect(); console.log('数据库连接成功!') } catch (err) { console.error('数据库连接失败:', err) // 连接失败后5秒自动重试 setTimeout(() => module.exports.connectToDB(), 5000); } } }
2. 延迟MongoClient实例初始化
避免在模块加载阶段就创建客户端实例,改为在连接函数内初始化,确保环境变量和网络就绪:
const { MongoClient } = require('mongodb'); let client = null; module.exports = { connectToDB: async () => { // 如果已有活跃连接,直接返回 if (client && client.topology?.isConnected()) { return client; } try { client = new MongoClient(process.env.MONGODB_URI, { connectTimeoutMS: 30000, socketTimeoutMS: 45000 }); await client.connect(); console.log('数据库连接成功!') return client; } catch (err) { console.error('数据库连接失败:', err) client = null; // 重试逻辑 setTimeout(() => module.exports.connectToDB(), 5000); throw err; } }, getClient: () => client }
3. 检查Azure网络配置
- 确认App Service出站规则未限制访问Cosmos DB的默认端口10255
- 若使用VNet集成,确保VNet与Cosmos DB之间已配置私有链接或防火墙白名单
- 把App Service的出站IP列表(在App Service「属性」中查看)添加到Cosmos DB的防火墙允许列表中
4. 利用MongoClient自动重连机制
MongoClient原生支持自动重连,确保你的mongodb驱动版本(建议4.x+)开启了该特性,同时可以通过heartbeatFrequencyMS参数调整心跳检测频率,及时发现连接状态变化。
内容的提问来源于stack exchange,提问作者user13692246
相关产品推荐
相关产品推荐

