You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 03:55:16