Nice programing

종료를 호출 한 후 핸드 셰이크를 대기열에 넣을 수 없습니다.

nicepro 2020. 10. 17. 12:24
반응형

종료를 호출 한 후 핸드 셰이크를 대기열에 넣을 수 없습니다.


여기에서 나는 약간의 기본적인 실수를하고있다. 일반적으로 나는 그런 코드를 구현했다.

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

그리고 모든 것이 훌륭하게 작동하지만 처음에만 쿼리를 "사용"하려면 두 번째로 그의 오류를 받았습니다.

종료를 호출 한 후 핸드 셰이크를 대기열에 넣을 수 없습니다.

.end () 연결을 시도했지만 도움이되지 않습니다
. 미리 감사드립니다
Radek


node-mysql 모듈을 사용하는 경우 .connect 및 .end를 제거하십시오. 직접 문제를 해결했습니다. 분명히 그들은 버그가 발생한 마지막 반복에서 불필요한 코드를 밀어 넣었습니다. createConnection 호출을 이미 실행 한 경우 연결할 필요가 없습니다.


에 따르면 :

TL; DR 연결이 createConnection끊길 때마다 메서드 를 호출하여 새 연결을 설정해야합니다 .

참고 : 웹 요청을 제공하는 경우 모든 요청에서 연결을 종료해서는 안됩니다. 서버 시작시 연결을 만들고 연결 / 클라이언트 개체를 사용하여 항상 쿼리하십시오. 오류 이벤트를 수신하여 서버 연결 해제를 처리하고 다시 연결할 수 있습니다. 여기에 전체 코드가 있습니다 .


에서:

그것은 말한다 :

서버 연결 해제

네트워크 문제, 서버 시간 초과 또는 서버 충돌로 인해 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);

위의 예에서 볼 수 있듯이 새 연결을 설정하여 연결을 다시 연결합니다. 일단 종료되면 기존 연결 개체는 설계 상 다시 연결할 수 없습니다.

풀을 사용하면 연결이 끊긴 연결이 풀에서 제거되어 다음 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;
}

연결 초기화 :

var connection = initializeConnection({
    host: "localhost",
    user: "user",
    password: "password"
});

사소한 제안 : 이것은 모든 사람에게 적용되는 것은 아니지만 범위와 관련된 사소한 문제에 부딪 혔습니다. OP가이 편집이 불필요하다고 생각하면 제거하도록 선택할 수 있습니다. 나를 위해, 나는의 라인 변경했다 initializeConnection이었다, var connection = mysql.createConnection(config);단순히로를

connection = mysql.createConnection(config);

그 이유는 if connection가 프로그램의 전역 변수 인 경우 이전에 문제 connection는 오류 신호를 처리 할 때 변수를 만들었 기 때문 입니다. 그러나 내 nodejs 코드에서 connection쿼리를 실행 하는 데 동일한 전역 변수를 계속 사용 했기 때문에 메서드 connection의 로컬 범위에서 새 변수 가 손실되었습니다 initalizeConnection. 그러나 수정시 전역 connection변수가 재설정되었는지 확인합니다. 다음과 같은 문제가 발생한 경우 관련이있을 수 있습니다.

치명적인 오류 후 쿼리를 대기열에 넣을 수 없습니다.

연결이 끊어진 후 쿼리를 수행 한 후 성공적으로 다시 연결 한 후 이것은 OP의 오타 일 수 있지만 명확히하고 싶었습니다.


나는 같은 문제가 있었고 Google이 나를 여기로 인도했습니다. 을 제거하는 것이 옳지 않다는 @Ata에 동의합니다 end(). 더 많은 인터넷 검색이 끝나면 사용 pooling하는 것이 더 좋은 방법 이라고 생각 합니다.

풀링에 대한 node-mysql 문서

다음과 같습니다.

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

pool.getConnection(function(err, connection) {
    connection.query( 'bla bla', function(err, rows) {
        connection.release();
    });
});

함수 내에서 connect () 및 end ()하지 마십시오. 이로 인해 함수에 대한 반복 호출에 문제가 발생합니다. 연결 만

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

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

});

그 연결을 다시 사용하십시오.

기능 내부

function insertData(name,id) {

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


}

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

이 문제는 내 것과 비슷하다고 생각합니다.

  1. MySQL에 연결
  2. MySQL 서비스 종료 (노드 스크립트를 종료하면 안 됨)
  3. MySQL 서비스 시작, 노드가 MySQL에 다시 연결
  4. DB 쿼리-> FAIL (치명적인 오류 후 쿼리를 대기열에 넣을 수 없습니다.)

I solved this issue by recreating a new connection with the use of promises (q).

mysql-con.js

'use strict';
var config          = require('./../config.js');
var colors          = require('colors');
var mysql           = require('mysql');
var q               = require('q');
var MySQLConnection = {};

MySQLConnection.connect = function(){
    var d = q.defer();
    MySQLConnection.connection = mysql.createConnection({
        host                : 'localhost',
        user                : 'root',
        password            : 'password',
        database            : 'database'
    });

    MySQLConnection.connection.connect(function (err) {
        if(err) {
            console.log('Not connected '.red, err.toString().red, ' RETRYING...'.blue);
            d.reject();
        } else {
            console.log('Connected to Mysql. Exporting..'.blue);
            d.resolve(MySQLConnection.connection);
        }
    });
    return d.promise;
};

module.exports = MySQLConnection;

mysqlAPI.js

var colors          = require('colors');
var mysqlCon        = require('./mysql-con.js');
mysqlCon.connect().then(function(con){
   console.log('connected!');
    mysql = con;
    mysql.on('error', function (err, result) {
        console.log('error occurred. Reconneting...'.purple);
        mysqlAPI.reconnect();
    });
    mysql.query('SELECT 1 + 1 AS solution', function (err, results) {
            if(err) console.log('err',err);
            console.log('Works bro ',results);
    });
});

mysqlAPI.reconnect = function(){
    mysqlCon.connect().then(function(con){
      console.log("connected. getting new reference");
        mysql = con;
        mysql.on('error', function (err, result) {
            mysqlAPI.reconnect();
        });
    }, function (error) {
      console.log("try again");
        setTimeout(mysqlAPI.reconnect, 2000);
    });
};

I hope this helps.


SOLUTION: to prevent this error(for AWS LAMBDA):

In order to exit of "Nodejs event Loop" you must end the connection, and then reconnect. Add the next code to invoke the callback:

connection.end( function(err) {
        if (err) {console.log("Error ending the connection:",err);}

       //  reconnect in order to prevent the"Cannot enqueue Handshake after invoking quit"

         connection = mysql.createConnection({
                host     : 'rds.host',
                port     :  3306,
                user     : 'user',
               password : 'password',
               database : 'target database'

               });
        callback(null, {
            statusCode: 200,
            body: response,

        });
    });

inplace of connection.connect(); use -

if(!connection._connectCalled ) 
{
connection.connect();
}

if it is already called then connection._connectCalled =true,
& it will not execute connection.connect();

note - don't use connection.end();


If you're trying to get a lambda, I found that ending the handler with context.done() got the lambda to finish. Before adding that 1 line, It would just run and run until it timed out.


You can use debug: false,

Example: //mysql connection

var dbcon1 = mysql.createConnection({
      host: "localhost",
      user: "root",
      password: "",
      database: "node5",
      debug: false,
    });

참고URL : https://stackoverflow.com/questions/14087924/cannot-enqueue-handshake-after-invoking-quit

반응형