Node-Mysql抛出连接超时

时间:2015-09-22 11:07:20

标签: javascript mysql node.js amazon-rds node-mysql

我的node.js应用程序因随机时间连接超时而给出5xx。以下是我连接和查询的方式:

var mysql = require('mysql');
var config = {  
            host: '172.10.1.1',
            port: 3306,
            user: 'user',
            password: 'pwd',
            database: 'mydb',
            connectionLimit: 15,
            queueLimit: 30
        }

var poolCluster = mysql.createPool(config);

var queryDB = function(query, cb) {
    poolCluster.getConnection(function(err, connection) {
        if(err) {
            cb(err, null);
        }
        else {
            connection.query(query, function (err, rows) {
                connection.release();
                cb(err, rows);
            });
        }
    });
};

此外,在另一个备用版本中,禁用了连接池,代码如下所示:

queryDB = function(query, cb) {
    var connection = mysql.createConnection(config);
    connection.query(query, function(err, rows) {
        connection.end();
        cb(err, rows);
    });
};

但两种设置都给出了 错误:连接ETIMEDOUT 在Connection._handleConnectTimeout

可以在此处看到与我当前设置类似的项目:https://github.com/hay-wire/NodeBootstrap/blob/master/models/UsersUtils.js

如果你能指出连接可能出现什么问题,那就太好了。感谢。

更新

由于node.js服务在集群模式下运行,我认为可能是跨线程的竞争条件从共享连接池获取mysql连接资源是原因。所以我关闭群集模式为单线程模式,连接超时停止。

我仍然不相信这是造成这个问题的竞争条件。有什么方法可以验证这个吗?

3 个答案:

答案 0 :(得分:4)

这与超时无关。我注意到以下内容(如果您在AWS Lambda函数中使用它,我认为这也适用于许多带回调的情况)。

在实际将COM_QUIT数据包发送到MySQL服务器以关闭连接之前,您正在调用connection.end();。所以下次你导入var mysql = require('mysql');时(至少在我的情况下)它会抛出一个超时错误,因为之前的连接似乎仍然对你的机器开放,但实际上已被MySQL关闭。

请参阅this link from directly from the documentation on terminating connections

要解决此问题,请使用.destroy()代替.end()

connection.query(query, function(err, rows) 
{            
    connection.destroy();
    cb(err, rows);                  
});

其他明智地使用.end()正确使用回调,如:

connection.query(query, function(err, rows) 
{            
    connection.end(function(errCon) //Don't do anything with end Error
    {
       // The connection is terminated now 
       cb(err, rows);
    });           
});

答案 1 :(得分:3)

有时会发生这种情况,默认的acquireTimeout有点低(10000ms),所以如果你有多个连接在运行,你应该增加它。您可以使用

在连接选项中进行设置
acquireTimeout: 1000000

var config = {  
        host: '172.10.1.1',
        port: 3306,
        user: 'user',
        password: 'pwd',
        database: 'mydb',
        connectionLimit: 15,
        queueLimit: 30,
        acquireTimeout: 1000000
}

答案 2 :(得分:0)

在执行以下代码时,我也收到连接超时错误。

[root@dub-mgrfarm113 dbhome_1]# pwd
/opt/oracle/product/19c/dbhome_1
[root@dub-mgrfarm113 dbhome_1]# echo $ORACLE_HOME
/opt/oracle/product/19c/dbhome_1/
[root@dub-mgrfarm113 dbhome_1]# echo $PATH

[oracle@dub-mgrfarm113 oracle]$ ./product/19c/dbhome_1/bin/lsnrctl stat

LSNRCTL for Linux: Version 19.0.0.0.0 - Production on 14-NOV-2019 11:16:45

Copyright (c) 1991, 2019, Oracle.  All rights reserved.

Message 1053 not found; No message file for product=network, facility=TNSTNS-12541: Message 12541 not found; No message file for product=network, facility=TNS
 TNS-12560: Message 12560 not found; No message file for product=network, facility=TNS
  TNS-00511: Message 511 not found; No message file for product=network, facility=TNS
   Linux Error: 111: Connection refused

我删除了con.connect()方法来解决此问题。现在工作正常。