解决node连接mysql长时间不操作数据库自动断开报错问题

最近项目部署上线后发现了一个数据库连接的问题,网上对于这个问题的解答也很少,后续自己找方法解决了,所以在这里记录一下。

问题是这样的,我用的node的express框架开发后端,项目部署上线后没什么问题,但是过了一段时间没去访问项目,也就是没有操作数据库后数据库就会断开连接(据说是因为mysql的默认配置连接时间是8小时,超过这个时间没有连接的话就会断开连接),mysql会报错Error:read ECONNRESET以及Error:Cannot enqueue Query after fatal error,这个时候访问项目就会报错,为了解决这个问题我也尝试了很多方法,无论是修改express连接mysql的配置项、express中监听mysql连接断开重连还是直接简单粗暴延长mysql的连接时间都不行,后面想了个办法,监听mysql断开连接后执行脚本命令重启express后端项目,这样虽然算是解决这个问题的偏方了但是效果确实不错,接下来讲讲具体代码实现吧

首先在js代码中执行终端命令需要用到child_process插件的exec命令,所以先安装一下child_process

shell 复制代码
npm install child_process

然后执行的终端命令是在项目启动的情况下重启项目,在这里我用pm2来实现重启的需求

首先引用官方的一句话来介绍一下pm2:PM2 是一个守护进程管理工具,帮助您管理和守护您的应用程序。它以简单直观的 C​​LI 命令行方式进行工作

简单来说就是可以管理node项目,以进程的方式启动项目并能保持项目不断开,同时还提供了很多api来操作启动的项目进程,我这里就需要用到pm2重启项目进程的apipm2 restart all

首先安装pm2

shell 复制代码
npm install pm2 -g

我的项目使用了docker,所以要是想在docker中配合使用pm2 的话,还需要在dockerfile中配置安装pm2,以pm2启动项目代替直接node启动项目

shell 复制代码
#node服务器
FROM node:16
LABEL name="blog-express4"
LABEL version="latest"
RUN mkdir -p /usr/src
COPY . /usr/src
WORKDIR /usr/src
RUN npm install
# 在当前docker实例中全局安装pm2
RUN npm install pm2 -g
EXPOSE 4000
# pm2启动项目代替直接node启动项目
# CMD ["node","app.js"]
CMD ["pm2-runtime","app.js"]

具体在docker中使用pm2的更多细节可以看pm2的官网:在docker中使用pm2

然后在项目连接mysql的配置文件中监听到mysql断开连接后执行pm2重启项目的api:

package.json配置node命令:

json 复制代码
{
  "name": "node-express4",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "pm2 start app.js",
    "restart": "pm2 restart all",
    "stop": "pm2 stop all",
    "logs": "pm2 logs",
    "ls": "pm2 ls"
  },
  "dependencies": {
    "busboy": "^1.6.0",
    "cookie-parser": "~1.4.4",
    "cors": "^2.8.5",
    "debug": "~2.6.9",
    "express": "~4.16.1",
    "http-errors": "~1.6.3",
    "jsonwebtoken": "^8.5.1",
    "morgan": "~1.9.1",
    "mysql": "^2.18.1",
    "pm2": "^5.3.0",
    "pug": "2.0.0-beta11"
  }
}

db/index.js数据库连接配置文件:

js 复制代码
//连接mysql数据库
var mysql = require('mysql')
var { exec } = require('child_process');
​
var mysqlConfig = {
  //连接远程数据库
  host: '114.55.75.3',
  user: 'root',
  // user: 'haixtx',  //docker部署mysql
  password: 'xxx',
  database: 'blog',
  port: 3306,
}
// 以pm2接管项目重新启动项目
var restartProject = function(){
  // process.exit()
  // 执行终端命令
  exec('npm run restart', (error, stdout, stderr) => {
    if (error) {
      console.error(`重启项目失败: ${error}`);
      return;
    }
    console.log(`重启项目成功: ${stdout}`);
  });
}
​
let connection
​
function handleDisconnect () {
  connection = mysql.createConnection(mysqlConfig)
​
  connection.connect((err) => {
    if (err) {
      // console.error('mysql连接错误,2s后重连: ' + err.stack)
      // // 2s后重连
      // setTimeout(handleDisconnect, 2000)
      return
    }
    console.log('数据库连接成功,mysql连接进程id: ' + connection.threadId)
  })
​
  // 监听MySQL连接的end事件,一旦连接断开则自动重连
  connection.on('end', function() {
    console.log('数据库连接已断开,pm2重启项目重连数据库...')
    // 执行exec终端命令
    restartProject()
  })
}
handleDisconnect ()
​
module.exports = connection

至此就解决了这一问题

项目的数据库长时间不操作后会自动重启后端项目重新连接数据库

相关推荐
指尖下的技术40 分钟前
Mysql面试题----MyISAM和InnoDB的区别
数据库·mysql
指尖下的技术2 小时前
Mysql面试题----为什么B+树比B树更适合实现数据库索引
数据结构·数据库·b树·mysql
Ciderw2 小时前
MySQL为什么使用B+树?B+树和B树的区别
c++·后端·b树·mysql·面试·golang·b+树
胡耀超3 小时前
CentOS 7.9(linux) 设置 MySQL 8.0.30 开机启动详解
linux·mysql·centos
计算机学姐6 小时前
基于微信小程序的民宿预订管理系统
java·vue.js·spring boot·后端·mysql·微信小程序·小程序
web2u9 小时前
MySQL 中如何进行 SQL 调优?
java·数据库·后端·sql·mysql·缓存
新知图书10 小时前
MySQL用户授权、收回权限与查看权限
数据库·mysql·安全
文城52110 小时前
Mysql存储过程(学习自用)
数据库·学习·mysql
沉默的煎蛋10 小时前
MyBatis 注解开发详解
java·数据库·mysql·算法·mybatis
C语言扫地僧11 小时前
MySQL 事务及MVCC机制详解
数据库·mysql