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

Azure App Service部署Node.js应用:mssql连接SQL Server失败排查

问题:Node.js Express部署到Azure App Service后无法连接SQL Server 2016

本地及Apache服务器上应用可正常连接SQL Server 2016执行查询,搭配React客户端运行无异常。但部署到Azure App Service后:

  • 非数据库查询路由可正常响应
  • 日志流显示SQL Server连接超时:ConnectionError: Failed to connect to XX.XXX.XX.XX:XXXX in 15000ms
  • 请求/getItems时sql.pool为undefined

已确认SQL Server配置管理器中TCP/IP启用、服务设为自动启动,调整mssql配置无效,需解决Azure环境下的适配问题。

相关代码:

mssql.js

var sql = require("mssql");
require("dotenv").config();

const config = {
  user: process.env.DB_USERNAME,
  password: process.env.DB_PASSWORD,
  server: process.env.DB_SERVER,
  port: JSON.parse(process.env.DB_PORT),
  database: process.env.DB_NAME,
  requestTimeout: 3600000, //an hour
  options: {
    trustServerCertificate: true,
    encrypt: true,
  },
  debug: true,
  parseJSON: true,
};

let pool;

const initConnect = async () => {
  try {
    const pool = await sql.connect(config);
    return pool;
  } catch (err) {
    console.log(err.message);
    console.log("Error connecting to DB...", err);
    sql.close();
  }
};

const initMod = async () => {
  this.pool = await initConnect();
  console.log("open connecion...");
};

initMod();

module.exports.pool = pool;
module.exports.SQLInst = sql;

server.js

const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const app = express();
const sql = require("./mssql");

const port = process.env.PORT || 3000;

app.use(cors());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

app.get("/", async (req, res) => {
  res.send("Welcome to test server!");
});

//  Getting items from db
app.get("/getItems", async (req, res) => {
  console.log(`Getting items...`);
  try {
    const data = await sql.pool.request().query("SELECT * FROM PartsPics");
    const items = await data.recordset;
    res.status(200).send(items);
  } catch (e) {
    console.log("Error occured: ", e);
    res.status(500).send(e);
  }
});

解决方案

1. 修复连接池初始化的作用域问题

当前代码中连接池的赋值存在作用域错误,导致导出的pool始终是初始的undefined。修改mssql.js如下:

var sql = require("mssql");
require("dotenv").config();

const config = {
  user: process.env.DB_USERNAME,
  password: process.env.DB_PASSWORD,
  server: process.env.DB_SERVER,
  port: parseInt(process.env.DB_PORT), // 替换JSON.parse,避免字符串转数字的潜在问题
  database: process.env.DB_NAME,
  requestTimeout: 3600000,
  options: {
    trustServerCertificate: true,
    encrypt: true,
  },
  debug: true,
  parseJSON: true,
};

let pool;

const initConnect = async () => {
  try {
    // 直接赋值给模块级变量,避免重新声明覆盖
    pool = await sql.connect(config);
    console.log("数据库连接成功");
    return pool;
  } catch (err) {
    console.error("连接数据库失败:", err.message);
    console.error(err);
    // 连接失败后终止进程,避免服务在无连接状态下运行
    process.exit(1);
  }
};

// 立即执行连接初始化
initConnect();

// 用getter导出pool,确保获取到最新的初始化后实例
module.exports = {
  get pool() {
    return pool;
  },
  SQLInst: sql
};

2. 配置Azure与SQL Server的网络权限

  • 如果使用的是Azure SQL Server:在防火墙设置中勾选允许Azure服务和资源访问此服务器,确保App Service能穿透防火墙
  • 如果是本地SQL Server:
    • 开放SQL Server对应端口(默认1433)的公网访问权限
    • 检查本地网络提供商是否拦截了该端口
  • 在Azure App Service的「配置-应用程序设置」中,确认所有数据库环境变量(DB_USERNAME、DB_PASSWORD等)填写正确,无拼写或格式错误

3. 优化路由中连接池的使用逻辑

添加连接池就绪检查,避免在初始化完成前调用:

// 修改server.js中的/getItems路由
app.get("/getItems", async (req, res) => {
  console.log("开始获取数据...");
  try {
    let pool = sql.pool;
    // 等待连接池初始化完成
    if (!pool) {
      await new Promise(resolve => setTimeout(resolve, 1000));
      pool = sql.pool;
      if (!pool) {
        return res.status(503).send("数据库连接未就绪,请稍后重试");
      }
    }
    const data = await pool.request().query("SELECT * FROM PartsPics");
    res.status(200).send(data.recordset);
  } catch (e) {
    console.error("获取数据出错:", e);
    res.status(500).send(e.message || "服务器内部错误");
  }
});

4. 调整连接配置兼容性

  • 根据SQL Server部署环境调整encrypt选项:本地SQL Server可尝试设置encrypt: false,Azure SQL Server保持encrypt: true
  • 确保trustServerCertificate的设置与SQL Server证书配置匹配

内容的提问来源于stack exchange,提问作者oz moyal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 11:53:16