web-dev-qa-db-ja.com

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);
    });
};

ただし、どちらの設定でもエラーが発生します。Connection._handleConnectTimeoutでETIMEDOUTに接続してください。

私の現在のセットアップと同様のプロジェクトはここで見ることができます: https://github.com/hay-wire/NodeBootstrap/blob/master/models/UsersUtils.js

接続で何がうまくいかないのかを指摘できれば素晴らしいと思います。ありがとう。

[〜#〜]更新[〜#〜]

Node.jsサービスはクラスターモードで実行されていたため、共有接続プールからmysql接続リソースを取得するためのスレッド間の競合状態が原因である可能性があります。そのため、私はクラスターモードをシングルスレッドモードに切り替え、接続タイムアウトを停止しました。

それでも、この問題の原因が競合状態であるとは確信していません。これを確認する方法はありますか?

7
Haywire

これはタイムアウトとは何の関係もありません。私は次のことに気づきました(AWS Lambda関数のようなもので使用している場合、これはコールバックのある多くの状況にも当てはまると思います)。

接続を閉じるために実際にCOM_QUITパケットをMySQLサーバーに送信する前に、connection.end();を呼び出しています。したがって、次にvar mysql = require('mysql');をインポートするとき(少なくとも私の場合)は、以前の接続がまだマシンに対して開いているように見えますが、実際にはMySQLによって閉じられているため、タイムアウトエラーがスローされます。

接続の終了に関するドキュメントから直接のこのリンク を参照してください。

したがって、この状態を修正するには、.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);
    });           
});
_
5
DR.

これは時々発生し、デフォルトの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
}
4
baao

また、次のコードの実行中に接続タイムアウトエラーが発生していました。

var mysql = require('mysql');

var con = mysql.createConnection({
  Host: "localhost",
  port:"3307",
  user: "root",
  password: "root",
  database:"nodedb"
});


/*
con.connect(function(err) {
  if (err) throw err;
  console.log("Connected!");
});
*/
module.exports=con;

この問題を解決するためにcon.connect()メソッドを削除しました。現在は正常に動作しています。

0
user2486108