解决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

至此就解决了这一问题

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

相关推荐
六月闻君11 分钟前
MySQL 报错:1137 - Can‘t reopen table
数据库·mysql
白云如幻40 分钟前
SQL99版链接查询语法
数据库·sql·mysql
爱吃烤鸡翅的酸菜鱼1 小时前
MySQL初学之旅(4)表的设计
数据库·sql·mysql·database
计算机毕设指导61 小时前
基于 SpringBoot 的作业管理系统【附源码】
java·vue.js·spring boot·后端·mysql·spring·intellij-idea
打鱼又晒网3 小时前
【MySQL】数据库精细化讲解:内置函数知识穿透与深度学习解析
数据库·mysql
tatasix4 小时前
MySQL UPDATE语句执行链路解析
数据库·mysql
天海华兮5 小时前
mysql 去重 补全 取出重复 变量 函数 和存储过程
数据库·mysql
武子康6 小时前
大数据-231 离线数仓 - DWS 层、ADS 层的创建 Hive 执行脚本
java·大数据·数据仓库·hive·hadoop·mysql
黑色叉腰丶大魔王6 小时前
《MySQL 数据库备份与恢复》
mysql
Ljw...6 小时前
索引(MySQL)
数据库·mysql·索引