调用退出后无法排队握手

rad*_*dek 75 node.js express

在这里,我正在做,可能是一些基本的错误,一般来说,我已经实现了这样的代码:

module.exports = {
    getDataFromUserGps: function(callback)
    {
        connection.connect();
        connection.query("SELECT * FROM usergps", 
            function(err, results, fields) {
                if (err) return callback(err, null);
                return callback(null, results);
            }
        ); 
        connection.end();
    },
    loginUser: function(login, pass, callback)
    {
        connection.connect();
        connection.query(
            "SELECT id FROM users WHERE login = ? AND pass = ?",
            [login, pass],
            function(err, results, fields) 
            {
                if (err) return callback(err, null);
                return callback(null, results);
            }
        ); 
        connection.end();
    },
    getUserDetails: function(userid, callback)
    {
        connection.connect();
        connection.query(
            "SELECT * FROM userProfilDetails LEFT JOIN tags ON userProfilDetails.userId = tags.userId WHERE userProfilDetails.userid = ?",
            [userid],
            function(err, results, fields)
            {
                if (err) return callback(err, null);
                return callback(null, results);
            }
        );
        connection.end();
    },
    addTags: function(userId, tags)
    {
        connection.connect();
        connection.query(
            "INSERT INTO tag (userId, tag) VALUES (?, ?)",
            [userId, tags],
            function(err, results, fields)
            {
                if (err) throw err;
            }
        )
        connection.end();
    }
}
Run Code Online (Sandbox Code Playgroud)

一切都很好,但只有第一次,如果我想第二次"使用"查询我收到他的错误:

调用退出后无法排队握手

我试过不要.end()连接,但它没有帮助
提前感谢
拉德克

And*_*yne 225

如果您使用node-mysql模块,只需删除.connect和.end.刚刚解决了这个问题.显然,他们在最后一次迭代中推送了不必要的代码,这也是错误的.如果已经运行了createConnection调用,则无需连接

  • 这是我找到的最糟糕的答案!当你创建一个连接,并且它打开时,现在,我们认为我们在一个函数中创建一个mysql节点,每次调用该函数时,它创建并保持打开连接,一段时间后,你得到mysql连接的Max Limit Reach (18认同)
  • @ata node-mysql实现了一个连接池.您不应该使用每个请求销毁连接对象,因为它不是实际请求.甚至不确定为什么你的评论会得到提升.很明显,人们不会阅读文档 (6认同)
  • 如果你在aws lambda中运行,如果你不关闭连接,lambda将保持超时.所以这些建议都无济于事.我在这个问题上花了好几天. (4认同)
  • 那你做错了.您应该重用该连接 (3认同)

XP1*_*XP1 49

根据:

TL; DR您需要createConnection在每次断开连接后调用该方法建立新连接.

注意:如果您正在提供Web请求,那么您不应该在每个请求上结束连接.只需在服务器启动时创建连接,并使用连接/客户端对象一直查询.您可以侦听错误事件以处理服务器断开连接和重新连接.完整代码 在这里.


从:

它说:

服务器断开连接

由于网络问题,服务器计时,或服务器崩溃,您可能会丢失与MySQL服务器的连接.所有这些事件都被认为是致命的错误,并且会有err.code = 'PROTOCOL_CONNECTION_LOST'.有关更多信息,请参阅错误处理部分.

处理此类意外断开连接的最佳方法如下所示:

function handleDisconnect(connection) {
  connection.on('error', function(err) {
    if (!err.fatal) {
      return;
    }

    if (err.code !== 'PROTOCOL_CONNECTION_LOST') {
      throw err;
    }

    console.log('Re-connecting lost connection: ' + err.stack);

    connection = mysql.createConnection(connection.config);
    handleDisconnect(connection);
    connection.connect();
  });
}

handleDisconnect(connection);
Run Code Online (Sandbox Code Playgroud)

正如您在上面的示例中所看到的,通过建立新连接来重新连接连接.终止后,无法通过设计重新连接现有连接对象.

使用Pool时,将从池中删除断开连接的连接,释放空间,以便在下一次getConnection调用时创建新连接.


我已经调整了函数,每次需要连接时,初始化函数会自动添加处理程序:

function initializeConnection(config) {
    function addDisconnectHandler(connection) {
        connection.on("error", function (error) {
            if (error instanceof Error) {
                if (error.code === "PROTOCOL_CONNECTION_LOST") {
                    console.error(error.stack);
                    console.log("Lost connection. Reconnecting...");

                    initializeConnection(connection.config);
                } else if (error.fatal) {
                    throw error;
                }
            }
        });
    }

    var connection = mysql.createConnection(config);

    // Add handlers.
    addDisconnectHandler(connection);

    connection.connect();
    return connection;
}
Run Code Online (Sandbox Code Playgroud)

初始化连接:

var connection = initializeConnection({
    host: "localhost",
    user: "user",
    password: "password"
});
Run Code Online (Sandbox Code Playgroud)

次要建议:这可能不适用于所有人,但我确实遇到了与范围有关的小问题.如果OP认为此编辑是不必要的,那么他/她可以选择将其删除.对我来说,我不得不换一条线initializeConnection,这var connection = mysql.createConnection(config);只是为了

connection = mysql.createConnection(config);
Run Code Online (Sandbox Code Playgroud)

原因是if connection是程序中的全局变量,之前的问题是connection在处理错误信号时你正在创建一个新变量.但是在我的nodejs代码中,我一直使用相同的全局connection变量来运行查询,因此新方法connection将在方法的本地范围内丢失initalizeConnection.但是在修改中,它确保connection重置全局变量如果您遇到一个被称为的问题,这可能是相关的

致命错误后无法排队查询

在失去连接后尝试执行查询然后成功重新连接之后.这可能是OP的拼写错误,但我只想澄清一下.


hbr*_*rls 21

我有同样的问题,谷歌带我到这里.我同意@Ata认为删除是不对的end().经过进一步的谷歌搜索,我认为使用pooling是一种更好的方式.

关于池的node-mysql doc

就像这样:

var mysql = require('mysql');
var pool  = mysql.createPool(...);

pool.getConnection(function(err, connection) {
    connection.query( 'bla bla', function(err, rows) {
        connection.release();
    });
});
Run Code Online (Sandbox Code Playgroud)


aji*_*jin 7

不要在函数内连接()和end().这将导致重复调用该函数时出现问题.仅建立连接

var connection = mysql.createConnection({
      host: 'localhost',
      user: 'node',
      password: 'node',
      database: 'node_project'
    })

connection.connect(function(err) {
    if (err) throw err

});
Run Code Online (Sandbox Code Playgroud)

一次并重用该连接.

功能内部

function insertData(name,id) {

  connection.query('INSERT INTO members (name, id) VALUES (?, ?)', [name,id], function(err,result) {
      if(err) throw err
  });


}
Run Code Online (Sandbox Code Playgroud)


Jam*_*nez 5

AWS Lambda 函数

使用mysql.createPool()connection.destroy()

这样,新调用使用已建立的池,但不保持函数运行。即使您没有获得池的全部好处(每个新连接都使用一个新连接而不是现有连接),它也使得第二次调用可以建立一个新连接,而不必先关闭前一个连接。

关于 connection.end()

这可能会导致后续调用引发错误。调用仍将稍后重试并工作,但会延迟。

关于mysql.createPool()connection.release()

Lambda 函数将继续运行,直到计划的超时,因为仍有打开的连接。

代码示例

const mysql = require('mysql');

const pool = mysql.createPool({
  connectionLimit: 100,
  host:     process.env.DATABASE_HOST,
  user:     process.env.DATABASE_USER,
  password: process.env.DATABASE_PASSWORD,
});

exports.handler = (event) => {
  pool.getConnection((error, connection) => {
    if (error) throw error;
    connection.query(`
      INSERT INTO table_name (event) VALUES ('${event}')
    `, function(error, results, fields) {
      if (error) throw error;
      connection.destroy();
    });
  });
};
Run Code Online (Sandbox Code Playgroud)