Nodejs Mysql长时间未响应字段断开连接问题

Nodejs Mysql长时间未响应字段断开连接问题

mysql默认当不活动状态下8个小时会自动断开连接以保证内存释放,但是nodejs当不使用第三方连接池时发现这是个很郁闷的问题,后来看到node的mysql中的readme文件有自动断开重连的例子,是通过监听connection的error来进行重连,代码就不放出了自己可以去readme文件查看或者github上也有类似代码,我想说的是,如果我用了connect-mysql模块,用到了通过mysql来保存session信息的话,这个重连接会不起作用,因为这块的代码是在app.js的 app.use(express.session({ secret: ‘supersecretkeygoeshere’, store: new MySQLStore({ client: mysql })));
中出写的所以重连并不会实时进行设置,这个问题不知如何解决


5 回复

Nodejs Mysql长时间未响应字段断开连接问题

在使用 Node.js 和 MySQL 时,经常遇到的一个问题是连接在长时间未响应的情况下会被自动断开。MySQL 默认会在不活动状态下 8 个小时自动断开连接,以确保内存得到释放。然而,这在某些应用场景下可能会成为一个问题,尤其是在没有使用连接池的情况下。

解决方案

对于这个问题,可以通过监听 connectionerror 事件来实现自动重连。具体来说,可以在创建数据库连接时添加错误监听器,以便在连接断开时自动重新建立连接。以下是一个简单的示例代码:

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

// 监听 error 事件,实现自动重连
connection.on('error', function(err) {
  console.error('MySQL Connection Error:', err);
  if (err.code === 'PROTOCOL_CONNECTION_LOST') {
    console.log('Database connection was closed. Attempting to reconnect...');
    // 递归调用自身来重新连接
    setTimeout(function() {
      connection.connect();
    }, 2000); // 等待2秒后再尝试重新连接
  }
});

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

使用 connect-mysql 模块

如果你使用了 connect-mysql 模块,并且用它来保存 session 信息,那么上述方法可能不会实时生效,因为这部分代码是在 app.js 中通过 express.session 来配置的。为了解决这个问题,你可以自定义一个 MySQLStore 类来覆盖默认的行为,从而实现自动重连的功能。

以下是一个示例代码:

const express = require('express');
const session = require('express-session');
const MySQLStore = require('connect-mysql')(session);

class CustomMySQLStore extends MySQLStore {
  constructor(options) {
    super(options);
  }

  get(key, callback) {
    super.get(key, (err, session) => {
      if (err && err.code === 'PROTOCOL_CONNECTION_LOST') {
        console.log('Database connection was lost. Attempting to reconnect...');
        this.client.connect(); // 重新连接数据库
      }
      callback(err, session);
    });
  }
}

const app = express();

app.use(session({
  secret: 'supersecretkeygoeshere',
  store: new CustomMySQLStore({ client: mysql })
}));

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

通过这种方式,你可以在获取 session 数据时检查并处理连接断开的情况,从而实现自动重连。这样即使在长时间未响应的情况下,应用也能继续保持与数据库的连接。

希望这些示例代码能帮助你解决 Node.js 和 MySQL 长时间未响应导致的连接断开问题。


谢谢 跟我遇到的问题一样,我也是这么解决的,但是当用到connect-mysql第三方包来存session信息时却解决不了

断开后重新取得session?

在Node.js应用中使用MySQL时,默认情况下,MySQL连接在不活动8小时后会自动断开。如果不使用连接池,可能会遇到连接断开的问题。node-mysql库提供了通过监听connectionerror事件来实现自动断开重连的功能。

如果你使用了connect-mysql模块来管理Session,并且希望在连接断开时能够自动重新连接,你需要确保在每次请求时都能正确处理连接的状态。以下是一个示例代码,展示如何使用连接池以及如何处理连接断开的情况:

示例代码

const express = require('express');
const mysql = require('mysql');
const session = require('express-session');
const MySQLStore = require('connect-mysql')(session);

const app = express();

// 创建连接池
const pool = mysql.createPool({
    connectionLimit: 10, // 连接池的最大连接数量
    host: 'localhost',
    user: 'root',
    password: 'password',
    database: 'mydb'
});

// 使用连接池来存储session
app.use(session({
    secret: 'supersecretkeygoeshere',
    store: new MySQLStore({ 
        client: pool 
    })
}));

// 监听连接错误并尝试重新连接
pool.on('error', (err) => {
    console.error('MySQL Pool Error:', err);
    // 可以在这里添加重新连接的逻辑
    // 例如:尝试重新创建连接池
    // pool.end();
    // pool = mysql.createPool(...);
});

app.get('/', (req, res) => {
    req.session.views = (req.session.views || 0) + 1;
    res.send(`You visited this page ${req.session.views} times`);
});

app.listen(3000, () => {
    console.log('Server is running on port 3000');
});

解释

  1. 创建连接池:使用mysql.createPool()创建一个连接池,这样可以有效地管理数据库连接。
  2. 配置Session Store:将Session Store配置为使用连接池,而不是直接使用MySQLStore创建新的连接。
  3. 监听连接错误:通过监听pool对象的error事件,可以在连接出现问题时执行相应的处理逻辑(如重新创建连接池)。

通过这种方式,可以确保即使在连接断开的情况下,你的应用也能够自动恢复连接并继续正常工作。

回到顶部