express中使用mysql ,运行长时间之后报read ECONNRESET

express中使用mysql ,运行长时间之后报read ECONNRESET

以下是使用了connect和end 的情况

exports.login = async (req, res, next) => {
  try {
    const username = req.body.reqdata.username;
    const password = req.body.reqdata.password;
    const sql = `select * from user where loginid='${username}' and password ='${password}'`;
    //console.log(sql)
db.connect()
    db.query(sql, (err, results, fields) => {
      console.log(results);
      console.log(err);
      if (err) {
        res.send({
          err: err.message,
        });
      }
      if (results.length > 0) {
        //生成token,并且在返回数据中返回,设置了60S失效的token
        const token = jwt.sign(req.body, "dsj", { expiresIn: 36000 });
        res.send({
          message: 0,
          data: results,
          token: token,
        });
      } else {
        res.send({
          message: 1,
          data: results,
        });
      }
    });
   db.end()
  } catch (err) {
    next(err);
  }
};

在每个请求中使用connect和end会导致只有第一次请求有返回,后续请求都报Cannot enqueue Handshake after invoking quit

如果不适用connect和end开启的时候能运行一段时间,长时间之后就报read ECONNRESET。

查阅了很多文章,尝试了在每次连接之后调用end来结束连接,这样就会导致只能第一次连接成功,后续的都失败,即使在每个请求之前重新使用connect也不行,很多文章说去掉end让mysql自己放掉连接,但这又会导致运行一段时间之后报read ECONNRESET。陷入了死循环,求解如何能解决上述问题并稳定运行?

回答不易,求求您采纳点赞哦

  • 看来这个问题是由于在您的 Express 应用程序中没有正确管理与 MySQL 数据库的连接引起的。通过在每个请求中调用db.connect()and db.end(),您正在为每个请求打开和关闭一个新连接,这在有大量请求时可能会导致问题。

  • 相反,您应该使用连接池来管理与 MySQL 数据库的连接。连接池允许您重用连接而不是为每个请求创建一个新连接。这有助于减少创建和关闭连接的开销,并防止出现“读取 ECONNRESET”和“调用退出后无法排队握手”等问题。

  • 您可以使用mysql2具有内置连接池功能的库或使用generic-pool包。

以下是如何在代码中使用连接池的示例:

const mysql = require('mysql2/promise');

// Create a connection pool
const pool = mysql.createPool({
  host: 'localhost',
  user: 'your_username',
  password: 'your_password',
  database: 'your_database',
  waitForConnections: true,
  connectionLimit: 10,
  queueLimit: 0
});

exports.login = async (req, res, next) => {
  try {
    const username = req.body.reqdata.username;
    const password = req.body.reqdata.password;
    const sql = `select * from user where loginid='${username}' and password ='${password}'`;

    // Get a connection from the pool
    const connection = await pool.getConnection();
    // Make the query
    const [rows, fields] = await connection.query(sql);
    // Release the connection back to the pool
    connection.release();
    if (rows.length > 0) {
      // generate token and return it in the response
      const token = jwt.sign(req.body, "dsj", { expiresIn: 36000 });
      res.send({
        message: 0,
        data: rows,
        token: token,
      });
    } else {
      res.send({
        message: 1,
        data: rows,
      });
    }
  } catch (err) {
    next(err);
  }
};

这样它只会打开有限数量的连接并重用它们,这将防止可用连接用完以及您遇到的错误。

不知道你这个问题是否已经解决, 如果还没有解决的话:

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^