node js:在查询之前检查 mysql 连接

node js: check mysql connection before a query

我将节点 js 与 mysql 一起使用,并希望避免应用程序在连接 errors.At 时崩溃:

function mysql_handleDisconnect() {
  mysql_connection = mysql.createConnection(mysql_config_obj); // Recreate the connection, since
                                                  // the old one cannot be reused.

  mysql_connection.connect(function(err) {              // The server is either down
    if(err) {                                     // or restarting (takes a while sometimes).
      console.log('error when connecting to db:', err);
      mysql_handleDisconnect(); // We introduce a delay before attempting to reconnect,
    }                                     // to avoid a hot loop, and to allow our node script to
  });                                     // process asynchronous requests in the meantime.
                                          // If you're also serving http, display a 503 error.
  mysql_connection.on('error', function(err) {
    console.log('db error', err);
    if(err.code === 'PROTOCOL_CONNECTION_LOST') { // Connection to the MySQL server is usually
      mysql_handleDisconnect();                         // lost due to either server restart, or a
    } else {                                      // connnection idle timeout (the wait_timeout
      throw err;                                  // server variable configures this)
    }
  });
}

 mysql_handleDisconnect(mysql_connection);

所以这是阻塞的,因为如果连接是closed.my,它会导致热循环使用 "mysql_connection.query('SELECT ...')" 查询。在这种情况下,应用程序崩溃。

所以我的问题是,是否可以在我进行查询之前检查连接?

在做任何事情之前尝试在每个微服务中使用以下代码:

 if(connection.state === 'disconnected'){
     return respond(null, { status: 'fail', message: 'server down'});
   }

与数据库的连接状态可能分为两种状态:

  1. 断开连接(由于数据库服务器关闭或数据库连接配置错误)
  2. 已通过身份验证(成功创建到数据库服务器的数据库连接时)。

所以要么检查 state == 'disconnected' 要么 state == 'authenticated'

我知道这是一个老问题,但我发现 connection.ping( (err) => {...}) 对于负载平衡器等进行的健康检查非常有用。

每次,当我在生产环境中推送我的代码时,mysql 连接都会丢失。这是生产中或本地非常常见的问题。
我的解决方案是在每次查询时建立数据库连接并在完成数据库查询后删除连接。 我的解决方案是每次查询前先建立数据库连接,然后在数据库查询完成后删除连接。

第 1 步:这是 dbConnection.js

的代码

//this code is for conenct to db
const mysql = require('mysql2');
require('dotenv').config();
module.exports.stablishedConnection = ()=>{
return new Promise((resolve,reject)=>{
  const con = mysql.createConnection( {
    host: process.env.DB_HOST||localhost,
    user: process.env.DB_USER_NAME||myUserName ,
    password: process.env.DB_PASSWORD||mypassword,
    database: process.env.DB_NAME||mydb
  });
  con.connect((err) => {
    if(err){
      reject(err);
    }
    resolve(con);
  });
  
})
}
module.exports.closeDbConnection =(con)=> {
  con.destroy();
}

第 2 步:对于 Router.js,我正在导入数据库连接并处理承诺

const router = require('express').Router();
const {stablishedConnection,closeDbConnection}  =require('../db/dbConnection');

router.get('/user/:sId/:userId',function(req,res){
  stablishedConnection()
  .then((db)=>{
    console.log("Db connection stablished");
    db.query(`select * from user WHERE  sent_id=${req.params.sId} AND user_id=${req.params.userId}`, null, function (err,data) { 
      if (!data) {
        res.status(200).json({sucess:false,err});
      }else{ 
        res.status(200).json({sucess:true,data});
        closeDbConnection(db);
         console.log("Db Connection close Successfully");
      }
  })                         
}).catch((error)=>{
  console.log("Db not connected successfully",error);
}); 
  
 
});
router.get('/sen/:userId',function(req,res){
  stablishedConnection()
  .then((db)=>{
    console.log("Db connection stablished");
    db.query(`select * from sen WHERE  user_id=${req.params.userId}`, null, function (err,data) { 
      if (!data) {
        res.status(200).json({sucess:false,err});
      }else{
        res.status(200).json({sucess:true,data});
        closeDbConnection(db);
        console.log("Db Connection close Successfully");
      }
  })                         
}).catch((error)=>{
  console.log("Db not connected successfully",error);
});   
});
router.get('/language',(req,res)=>{
  stablishedConnection()
  .then((db)=>{
    console.log("Db connection stablished");
    db.query("select * from language", null, function (err,data) { 
      if (!data) {
        res.status(200).json({sucess:false,err});
      }else{
        res.status(200).json({sucess:true,data});
        closeDbConnection(db);
         console.log("Db Connection close Successfully")
      }
  })                         
}).catch((error)=>{
  console.log("Db not connected successfully",error);
}); 
})

module.exports = router;

这是完美的运行如果你想在每次查询时创建和关闭连接..

我是这样解决这个问题的:

let connection = mysql.createConnection(DB_CONFIG);
function runDBQuery() {
  const disconnected = await new Promise(resolve => {
    connection.ping(err => {
      resolve(err);
    });
  });
  if (disconnected) {
    connection = mysql.createConnection(DB_CONFIG);
  }
  ... use actual connection
}