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

Node.js使用MySQL连接池每日请求超时,服务停滞需重启求助

问题描述

我在Node.js服务器中使用MySQL连接池处理数据库连接,该服务器为Web应用提供服务,部署在Heroku平台,MySQL数据库托管于Google SQL。每日会出现数次服务完全停滞的情况,必须重启服务器才能恢复,经排查发现问题在于某一时刻所有数据库请求均会超时。

连接池初始化代码

global.pool;

function initPool()  // called on Server starts
{
  const mysql = require("mysql"); // mysql@2.18.1
  pool = mysql.createPool({
                           connectionLimit : 30,
                           host     : '******',
                           port     : '******',
                           user     : '******',
                           password : '******',
                           database : '******',
                           waitForConnections : true   // If true, the pool will queue the connection request and call it when one becomes available. 
                          }); 

    pool.on('acquire', function (connection) {
      console.log('[mysql] Connection %d acquired', connection.threadId);
    });     

    pool.on('connection', function (connection) {
      console.log('[mysql] Connection %d connected', connection.threadId);   
    });     

    pool.on('enqueue', function () {
      console.log('[mysql] enqueue. waiting for available connection slot');
    });

    pool.on('release', function (connection) {
      console.log('[mysql] Connection %d released', connection.threadId);
    });                        
    pool.on('error', function (err) {
      console.error(err);
}); 
}

查询执行代码

static getSomething(condition)
{
  var deferred = Q.defer();
   var query = ` 
                  SELECT *
                  FROM table
                  WHERE field = "${condition}";        
                `;
   pool.query(query, function(error, results, fields)
     {
       if(error) 
         {
          deferred.reject(error);
          return;
         }
       deferred.resolve(results);
     });
  return deferred.promise;         
}

请问我是否忽略了某些配置问题?为何每日都需要重启服务器?是否需要采用不同的方式管理数据库连接的开闭?


问题分析与解决方案

1. 缺失连接有效性检测配置

Google Cloud SQL与Heroku之间的跨云网络容易出现闲置连接被防火墙断开的情况,当前连接池未配置连接存活检测与超时参数,导致失效连接长期占用池资源,最终耗尽所有可用连接。

需补充以下关键配置:

pool = mysql.createPool({
  connectionLimit: 30,
  host: '******',
  port: '******',
  user: '******',
  password: '******',
  database: '******',
  waitForConnections: true,
  connectTimeout: 10000,       // 10秒内无法建立连接则超时
  acquireTimeout: 10000,       // 10秒内无法获取池连接则超时
  waitTimeout: 60000,          // 连接闲置60秒后自动释放
  keepAlive: true,             // 启用连接心跳
  keepAliveInitialDelay: 30000 // 连接建立30秒后开始发送心跳包
});

2. 错误处理不完善导致连接泄漏

当前pool.on('error')仅打印错误,未处理失效连接;单个连接出错时也未主动销毁,导致无效连接留在池中,后续请求反复尝试使用这些连接,最终占满连接池。

优化错误处理逻辑:

// 池级错误处理
pool.on('error', function (err) {
  console.error('[mysql] Pool error:', err);
  // 连接丢失时重建池(或让池自动处理)
  if (err.code === 'PROTOCOL_CONNECTION_LOST') {
    initPool();
  } else {
    throw err;
  }
});

// 单个连接的错误处理
pool.on('connection', function (connection) {
  console.log('[mysql] Connection %d connected', connection.threadId);
  connection.on('error', function(err) {
    console.error('[mysql] Connection %d error:', connection.threadId, err);
    // 主动销毁出错的连接,避免占用池资源
    connection.destroy();
  });
});

3. 字符串拼接SQL引发的风险

当前查询用字符串拼接生成SQL,存在严重SQL注入风险,同时若condition包含特殊字符,可能导致查询执行阻塞,占用连接不释放。必须改用参数化查询:

static getSomething(condition) {
  var deferred = Q.defer();
  // 使用?作为占位符,由驱动自动处理参数转义
  const query = 'SELECT * FROM table WHERE field = ?';
  pool.query(query, [condition], function(error, results, fields) {
    if(error) {
      deferred.reject(error);
      return;
    }
    deferred.resolve(results);
  });
  return deferred.promise;         
}

4. 无队列长度限制引发服务雪崩

waitForConnections: true会让所有请求进入队列等待连接,若队列无限增长,会耗尽内存导致服务停滞。需设置queueLimit限制队列长度,超出时直接返回错误:

pool = mysql.createPool({
  // ... 其他配置
  queueLimit: 100 // 最多允许100个请求排队等待
});

5. 连接数配置可能超限

Google Cloud SQL实例有连接数配额限制(基础实例通常为25-100),当前connectionLimit:30可能接近或超出配额,需查看实例配额后调整该值,避免被数据库端拒绝连接。

核心原因总结

每日服务停滞的根本原因是失效连接未被及时回收,导致连接池耗尽,所有请求排队等待超时。通过上述配置优化与代码调整,即可解决问题,无需频繁重启服务器。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 13:04:57