Nodejs中使用mysql的pool模式超过十分钟会连接不上数据库

Nodejs中使用mysql的pool模式超过十分钟会连接不上数据库

var pool = mysql.createPool({‘host’:‘127.0.0.1’,‘user’:‘testdbu’,‘password’:‘test’,‘database’:‘test’});
pool.getConnection(function(err,client) {
if (err) console.log(“DB pool => " + err);
var sql  =  “SELECT id,title,name FROM people WHERE t_hash=”+mysql.escape(uri[2])+” LIMIT 1";
client.query(sql,function(error,results){
if(error) {
console.log('hh - ',error.code);
}
if(results.length > 0) {
res.write(results[0][‘name’]);
}else{
res.writeHead(404,{‘Content-Type’:‘text/html’});
res.write(‘The page not found!’);
}
client.release();
res.end();
});
});

控制台 报错 为 : hh - ECONNRESET 这是什么原因? 我到 mysql 上去 show processlist 发现那个链接还在 ,是sleep 状态,mysql 的 wait_timeout 是 28800


6 回复

Node.js 中使用 MySQL 的 Pool 模式超过十分钟会连接不上数据库

问题描述

在使用 Node.js 的 mysql 模块通过连接池(pool)模式连接 MySQL 数据库时,如果超过十分钟,客户端尝试从连接池获取连接时会报错 ECONNRESET。错误信息显示为 hh - ECONNRESET

原因分析

ECONNRESET 错误通常表示连接被远程主机重置。在本例中,可能是由于 MySQL 服务器的配置导致连接在长时间闲置后被自动关闭。尽管你在 MySQL 中查看 show processlist 发现连接处于 Sleep 状态,并且 wait_timeout 设置为 28800 秒(即 8 小时),但仍然可能存在一些配置问题或连接管理问题。

解决方案

  1. 设置连接池的超时时间: 你可以通过配置连接池来调整连接的超时时间。这可以通过设置 acquireTimeoutidleTimeoutMillis 来实现。

  2. 定期检查并刷新连接池: 你可以定时执行一些查询来保持连接活跃,避免长时间闲置导致连接被 MySQL 自动关闭。

以下是修改后的代码示例:

const mysql = require('mysql');
const pool = mysql.createPool({
    host: '127.0.0.1',
    user: 'testdbu',
    password: 'test',
    database: 'test',
    acquireTimeout: 30000, // 30秒超时
    idleTimeoutMillis: 30000 // 30秒空闲超时
});

// 定期执行查询以保持连接活跃
setInterval(() => {
    pool.query('SELECT 1', (err, results) => {
        if (err) console.error('Error refreshing connection:', err);
    });
}, 5 * 60 * 1000); // 每5分钟刷新一次

// 查询逻辑
pool.getConnection((err, client) => {
    if (err) {
        console.log("DB pool => " + err);
        return;
    }

    const uri = ['some_value']; // 假设这是你的uri数组
    const sql = `SELECT id, title, name FROM people WHERE t_hash=${mysql.escape(uri[2])} LIMIT 1`;

    client.query(sql, (error, results) => {
        if (error) {
            console.log('hh - ', error.code);
        } else if (results.length > 0) {
            console.log(results[0]['name']);
        } else {
            console.log('The page not found!');
        }

        client.release(); // 释放连接
    });
});

解释

  • acquireTimeout: 设置连接获取超时时间,单位为毫秒。
  • idleTimeoutMillis: 设置连接空闲超时时间,单位为毫秒。
  • setInterval: 定期执行查询以保持连接活跃,避免长时间闲置导致连接被 MySQL 自动关闭。
  • client.release(): 在完成查询后释放连接回连接池,以便其他请求可以复用该连接。

通过以上配置和处理方式,可以有效解决长时间闲置导致的连接问题。


黑科技:每隔一分钟,来一个“心跳查询”吧。。。

不好意思,手机操作不便,把回复误删了。可以直接pool.query()。源码中有这个方法。不过你还是需要心跳查询以保持连接。

我的做法是自己做连接池,通过取余均衡负载,一小时换掉一批mysql连接。

额,看来怎么都是得 心跳查询了, 是不是不够优雅?

这个问题可能是由于MySQL服务器的空闲连接超时设置导致的。默认情况下,MySQL会在一段时间内(通常是8小时)关闭没有活动的连接。即使使用了Node.js的mysql模块中的连接池(pool),如果连接长时间处于空闲状态,也可能会遇到类似的问题。

解决方法

可以通过调整MySQL服务器配置或通过Node.js应用程序定期执行查询来保持连接活跃。

方法1: 调整MySQL服务器配置

在MySQL配置文件中(通常是my.cnfmy.ini),增加以下配置项来延长空闲连接的超时时间:

[mysqld]
wait_timeout = 28800
interactive_timeout = 28800

然后重启MySQL服务以使更改生效。

方法2: 在Node.js中保持连接活跃

你可以创建一个定时任务,每隔一段时间发送一个简单的查询(例如SELECT 1)来保持连接活跃。下面是一个示例代码,展示如何实现这一点:

const mysql = require('mysql');
const pool = mysql.createPool({
    host: '127.0.0.1',
    user: 'testdbu',
    password: 'test',
    database: 'test'
});

function keepConnectionAlive() {
    pool.query('SELECT 1', (err) => {
        if (err) {
            console.error('Error keeping connection alive:', err);
        } else {
            console.log('Connection is kept alive.');
        }
    });
}

// 每隔10分钟(600000毫秒)发送一次保持连接的查询
setInterval(keepConnectionAlive, 600000);

// 执行你的查询逻辑
pool.getConnection((err, client) => {
    if (err) console.log("DB pool => " + err);
    const sql = "SELECT id,title,name FROM people WHERE t_hash=" + mysql.escape(uri[2]) + " LIMIT 1";
    client.query(sql, (error, results) => {
        if (error) {
            console.log('hh - ', error.code);
        }
        if (results.length > 0) {
            res.write(results[0]['name']);
        } else {
            res.writeHead(404, {'Content-Type': 'text/html'});
            res.write('The page not found!');
        }
        client.release();
        res.end();
    });
});

这段代码中,keepConnectionAlive函数会每10分钟发送一次简单的查询,以确保连接不会被MySQL服务器关闭。

回到顶部