如何在每次请求 Express 后关闭 mysql 连接?

How do I close mysql connection after each request with Express?

我有一个这样的路由器文件:

import express from 'express';
import health from './health';
import surface from './surface';

const router = express.Router();

router.use('/health', health);
router.use('/surface', surface);

router.get('*', (req, res) => {
  res.status(404);
  res.json({
    message: 'Uknown API endpoint'
  });
});

export default router;

在每个路由中,我使用 NPM mysql 包创建连接,然后在我调用 res.send() 之前结束它。 IIRC 创建一个连接并在每次查询时结束它是一个坏主意。

我试过像这样做中间件:

router.use((req, res, next) => {
  next();
  mySingletonWrappingMysql.connection.end();
});

鉴于我的路由正在执行异步操作,endConnection 调用发生得太早了。 next 并不是真正的异步,所以我不能 await next 而且我什至不确定 way/place 这样做是否正确。这个例子使用的是单例,因为我也不确定如何正确设置要在路由中使用的新实例。 req.param 似乎不是最佳选择,因为它似乎适用于特殊查询参数变量。

您需要连接池 MySQL。这是一个可连续重用的连接资源池。需要的时候拿一个,用完就放手。因此,每个请求,甚至每个中间件调用,都可以使用连接而不必担心并发性(这不适用于连接)。看到这个。 https://www.npmjs.com/package/mysql#pooling-connections

像这样设置您的游泳池,只需一次。每个 node.js 服务器实例都需要一个池,用于它使用的每个单独的 MySQL 服务器。

var mysql = require('mysql');
var pool  = mysql.createPool({
  connectionLimit : 10,
  host            : 'example.org',
  user            : 'bob',
  password        : 'secret',
  database        : 'my_db'
});

此 createPool 操作创建一个最多包含十个连接的池。每次使用池时,它都会检查它的所有连接是否都忙。如果没有,它会给你一个闲置的使用。如果他们都忙,它会打开一个新的。但是,如果池中已经有 connectionLimit 个连接在使用中,它会一直等到有空闲连接为止。

然后随意的一次性查询就像这样。在 REST 服务器中,您可能会发现一些 GET 查询可以通过对数据库的单个查询来满足。这些超级简单。无需显式地从池中获取或释放连接。而且,当您释放连接时,它会保持与 DBMS 的连接,以供将来的请求使用。如果满足特定请求需要两个或三个 SELECT 查询,您也可以使用此技术。但是,每个查询可能使用来自池的不同连接。

 pool.query('SELECT whatever FROM whatever', 
   function (error, results, fields) {
     if (error) throw error;
     /* handle your results array */
 })

如果您需要为多个查询获取连接,这几乎是一样简单,但您确实需要记住在完成后 release() 连接。当您的某些查询依赖于序列中先前查询的结果时,您需要执行此操作。

pool.getConnection(function(err, connection) {
    if (error) throw error;
    connection.query('INSERT INTO sometable ...', 
       function (error, results, fields) {
           if (error) {
               connection.release();
               throw error;
           }
           connection.query('INSERT INTO detail ... (LAST_INSERT_ID()...)', 
               function (error, results, fields) {
                  connection.release();
                  if (error) throw error;
               });
       });
});

您可能想改用 promises 来避免这种函数嵌套,尤其是当您想要 运行 一系列查询时。