Nodejs环境下MySQL会自动断开链接吗?

Nodejs环境下MySQL会自动断开链接吗?

我使用的是node-mysql 网站放在服务器上有一天多了,今天发现网站访问不了了,上服务器查看,node的报错信息是Connection lost:The server closed the connection 。请问这是MySQL的机制吗,难道隔一段时间就会断开连接?请问各位是有没有遇到过这种问题?如何处理的?

6 回复

Node.js环境下MySQL会自动断开链接吗?

在Node.js环境下使用MySQL数据库时,确实有可能遇到连接被自动断开的情况。这种情况通常由MySQL服务器端的配置决定,例如超时时间、空闲连接的时间等。node-mysql库(现在更推荐使用mysql2)在处理这类情况时提供了相应的解决方案。

1. 连接丢失的原因

当你看到错误信息 Connection lost: The server closed the connection 时,这通常意味着MySQL服务器主动关闭了连接。这可能是由于以下几个原因:

  • 超时设置:MySQL服务器可能设置了空闲连接的超时时间,如果连接空闲时间超过了这个值,服务器可能会关闭该连接。
  • 网络问题:如果服务器或客户端之间的网络不稳定,也可能导致连接中断。
  • 服务器重启:如果MySQL服务器意外重启或停止运行,所有现有的连接都会被关闭。

2. 解决方案

为了解决这个问题,你可以采取以下几种方法:

a. 使用持久化连接

一种常见的做法是在应用启动时建立一个全局的数据库连接池,并在整个应用生命周期中重用这个连接池。这样可以避免频繁地创建和销毁连接。

const mysql = require('mysql');
const pool = mysql.createPool({
  host: 'localhost',
  user: 'root',
  password: 'password',
  database: 'testdb',
  connectionLimit: 10, // 最大连接数
});

// 在需要使用数据库的地方从连接池获取连接
pool.getConnection((err, connection) => {
  if (err) throw err;
  connection.query('SELECT * FROM users', (err, rows) => {
    if (err) throw err;
    console.log(rows);
    connection.release(); // 释放连接
  });
});
b. 设置连接重试逻辑

你还可以在捕获到连接丢失错误时实现自动重连机制。

pool.on('connection', (connection) => {
  connection.on('error', (err) => {
    if (err.code === 'PROTOCOL_CONNECTION_LOST') {
      console.error('Database connection was closed.');
      // 重新连接
      pool.getConnection((err, newConnection) => {
        if (err) {
          console.error('Failed to reconnect:', err);
          setTimeout(() => {
            pool.emit('connection', connection); // 重试
          }, 2000);
        }
      });
    }
  });
});

通过这些方法,你可以有效地管理Node.js应用与MySQL数据库之间的连接,减少因连接丢失而导致的服务中断。


会 可以参考http://cnodejs.org/topic/516b77e86d382773064266df

谢谢! 顺便问一个问题,node.js是单线程执行任务的,所以mysql的connection只用一个全局的connection就行了吗?用不用close掉?

需要close掉,建议用连接池。

现在node.js 也是往多进程方向进发。

在Node.js环境中使用node-mysql库时,MySQL确实有可能自动断开连接。这通常是由于长时间不活动导致的,因为MySQL服务器为了节约资源可能会主动关闭空闲的连接。此外,网络故障、服务重启等也可能会导致连接中断。

如何处理?

  1. 重连机制:为了解决这个问题,你可以实现一个重连机制,在检测到连接丢失后尝试重新建立连接。
  2. 设置心跳包:定期发送查询或者执行命令(如 SELECT 1)以保持连接活跃。

示例代码

下面是一个简单的示例,展示如何实现一个重连机制:

const mysql = require('mysql');
const connection = mysql.createConnection({
    host: 'localhost',
    user: 'root',
    password: 'password',
    database: 'testdb'
});

connection.connect((err) => {
    if (err) {
        console.error('Error connecting to MySQL:', err.stack);
        return;
    }
    console.log('Connected to MySQL as id ' + connection.threadId);
});

// 监听错误事件,以便在发生错误时重新连接
connection.on('error', (err) => {
    console.error('Database error:', err.code);
    if (err.code === 'PROTOCOL_CONNECTION_LOST') {
        console.log('Lost connection, attempting to reconnect...');
        connection.connect();
    }
});

// 每隔一定时间发送一个ping来保持连接
setInterval(() => {
    connection.query('SELECT 1', (err, results) => {
        if (err) {
            console.error('Ping failed:', err);
        } else {
            console.log('Ping successful');
        }
    });
}, 5000); // 每5秒发送一次ping

解释

  • 我们监听了connection对象上的error事件,这样可以捕获到任何连接错误,并且当错误类型是PROTOCOL_CONNECTION_LOST时,表示连接已丢失,我们尝试重新连接。
  • 使用setInterval函数每隔5秒发送一次SELECT 1查询,这是一种常用的方法来保持连接活跃,防止因长时间无操作而导致的连接丢失。

通过这种方式,你的应用可以在MySQL连接丢失后自动恢复,从而减少服务中断的时间。

回到顶部