Node.js、请求、MySQL 和连接池导致无限阻塞/冻结行为?

2023-12-30

我正在开发一个连接到 REST 服务、获取响应、转换响应并将其写入数据库的服务。我最初在概念验证中使用平面文件,一切正常。现在,在 10-15 个请求之后,脚本就会挂起。我收到了所有 30 个处理平面文件的请求,而处理数据库的请求只有三分之一到一半。

我开始编写一个测试用例来隔离正在发生的事情,结果发现在删除了所有实际的应用程序逻辑、数据库模式和请求信息后,我得到了这样的结果:

var mysql = require('mysql');
var pool  = mysql.createPool({
  host     : 'localhost',
  user     : 'user',
  password : 'secret',
});

while (true) {
        pool.getConnection(function (err, connection) {
            if (err) throw err;
            connection.query('SELECT 1 + 1 AS solution', function(err, rows, fields) {
              if (err) throw err;
              console.log('The solution is: ', rows[0].solution);
              connection.end();
            });
        });
}

据我想象,这是使用连接池执行某些操作的最少量的代码。运行时,命令行中不会记录任何内容。去除while {}块,它按预期运行一次,然后退出。

我的期望是池大小将提供约束,虽然它会很快查询 mysql,但它永远不会增长超过特定大小。相反,它似乎从未尝试建立联系。


根据 Daniel 关于异步库以及何时调用的评论进行编辑connection.end()。我遵循异步库在这里实现的逻辑,您应该尽早释放资源,但有些东西仍然阻塞。将查询结果打印到控制台一次,然后“挂起”。

var mysql = require('mysql'),
    async = require('async');
var pool = mysql.createPool({
  host     : 'localhost',
  user     : 'user',
  password : 'secret',
});



async.forever(function() {
                        pool.getConnection(function (err, connection) {
                            if(err) throw err;
                            connection.query('SELECT 1 + 1 AS solution', 
                              function(err, rows, fields) {
                              connection.end();
                              if (err) throw err;
                              console.log('The solution is: ', rows[0].solution);
                            });

                        });
            },
            function (err) {
                console.log(err);
            });

我对被困在这样的情况感到不舒服 - 看起来要么async or mysql违反了异步的承诺......有什么想法吗?


您正在使用同步循环来部署异步资源。你不能那样做。

你的 while 循环填满了数据库池,然后再次循环并阻塞getConnection然后它会阻塞整个 Node.js 事件循环。

您可以使用async包来执行异步 while 循环。

The 异步#永远 https://github.com/caolan/async#forevercall 会做你想要实现的目标。


此外,您的代码正在泄漏数据库连接。你应该把connection.end()首先在回调中,除非您要再次使用相同的连接。否则,错误将导致数据库连接泄漏。

pool.getConnection(function (err, connection) {
    if (err) throw err;
    connection.query('SELECT 1 + 1 AS solution', function(err, rows, fields) {
      connection.end(); // return to pool before evaluating error.
      if (err) throw err;
      console.log('The solution is: ', rows[0].solution);
    });
});
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Node.js、请求、MySQL 和连接池导致无限阻塞/冻结行为? 的相关文章

随机推荐