Node.js MySQL 영구 연결 필요
노드 웹 앱을 위한 지속적인 MySQL 연결이 필요합니다.문제는 이런 일이 하루에 몇 번씩 일어난다는 것입니다.
Error: Connection lost: The server closed the connection.
at Protocol.end (/var/www/n/node_modules/mysql/lib/protocol/Protocol.js:73:13)
at Socket.onend (stream.js:79:10)
at Socket.EventEmitter.emit (events.js:117:20)
at _stream_readable.js:895:16
at process._tickCallback (node.js:415:13)
error: Forever detected script exited with code: 8
error: Forever restarting script for 2 time
info: socket.io started
내 연결 코드는 다음과 같습니다.
// Yes I know multipleStatements can be dangerous in the wrong hands.
var sql = mysql.createConnection({
host: 'localhost',
user: 'my_username',
password: 'my_password',
database: 'my_database',
multipleStatements: true
});
sql.connect();
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);
sql = mysql.createConnection(connection.config);
handleDisconnect(sql);
sql.connect();
});
}
handleDisconnect(sql);
보시다시피 핸들 Disconnect 코드가 작동하지 않습니다.
mysql 연결 풀을 사용합니다.연결이 끊어지면 다시 연결되며 동시에 여러 sql 쿼리를 만들 수 있는 추가적인 이점을 얻을 수 있습니다.데이터베이스 풀을 사용하지 않으면 현재 실행 중인 데이터베이스 요청이 완료되기를 기다리는 동안 앱이 데이터베이스 요청을 차단합니다.
저는 보통 질의를 경로와 분리하여 보관하는 데이터베이스 모듈을 정의합니다.이렇게 생겼네요...
var mysql = require('mysql');
var pool = mysql.createPool({
host : 'example.org',
user : 'bob',
password : 'secret'
});
exports.getUsers = function(callback) {
pool.getConnection(function(err, connection) {
if(err) {
console.log(err);
callback(true);
return;
}
var sql = "SELECT id,name FROM users";
connection.query(sql, [], function(err, results) {
connection.release(); // always put connection back in pool after last query
if(err) {
console.log(err);
callback(true);
return;
}
callback(false, results);
});
});
});
이것이 엄청나게 지연되는 것은 알지만, 좀 더 일반적이고 사용하기 쉬운 해결책을 써 보았습니다.나는 완전히 의존하는 앱을 작성했습니다.connection.query()수영장으로 갈아타면 그런 전화들이 끊겼습니다
제 해결책은 이렇습니다.
var mysql = require('mysql');
var pool = mysql.createPool({
host : 'localhost',
user : 'user',
password : 'secret',
database : 'test',
port : 3306
});
module.exports = {
query: function(){
var sql_args = [];
var args = [];
for(var i=0; i<arguments.length; i++){
args.push(arguments[i]);
}
var callback = args[args.length-1]; //last arg is callback
pool.getConnection(function(err, connection) {
if(err) {
console.log(err);
return callback(err);
}
if(args.length > 2){
sql_args = args[1];
}
connection.query(args[0], sql_args, function(err, results) {
connection.release(); // always put connection back in pool after last query
if(err){
console.log(err);
return callback(err);
}
callback(null, results);
});
});
}
};
풀을 한 번 인스턴스화한 다음 이름이 지정된 메서드를 내보냅니다.query. 지금, 언제connection.query()는 아무 곳에서나 호출되며, 이 메서드는 먼저 풀에서 연결을 잡은 다음 인수를 연결로 전달합니다.콜백을 먼저 잡는 부가적인 효과가 있어 풀에서 연결을 잡을 때 발생하는 오류를 콜백할 수 있습니다.
이것을 사용하기 위해서는 mysql 대신 모듈로 필요합니다.예:
var connection = require('../middleware/db');
function get_active_sessions(){
connection.query('Select * from `sessions` where `Active`=1 and Expires>?;', [~~(new Date()/1000)], function(err, results){
if(err){
console.log(err);
}
else{
console.log(results);
}
});
}
이것은 일반 쿼리와 똑같이 보이지만 실제로는 풀을 열고 백그라운드의 풀에서 연결을 가져옵니다.
@gladsocc 질문에 대한 답변:
모든 것을 리팩토링하지 않고 수영장을 사용할 수 있는 방법이 있습니까?저는 앱에 수십 개의 SQL 쿼리가 있습니다.
이것이 바로 제가 만든 것입니다.쿼리 기능을 위한 포장지입니다.연결을 잡고 쿼리를 수행한 다음 연결을 해제합니다.
var pool = mysql.createPool(config.db);
exports.connection = {
query: function () {
var queryArgs = Array.prototype.slice.call(arguments),
events = [],
eventNameIndex = {};
pool.getConnection(function (err, conn) {
if (err) {
if (eventNameIndex.error) {
eventNameIndex.error();
}
}
if (conn) {
var q = conn.query.apply(conn, queryArgs);
q.on('end', function () {
conn.release();
});
events.forEach(function (args) {
q.on.apply(q, args);
});
}
});
return {
on: function (eventName, callback) {
events.push(Array.prototype.slice.call(arguments));
eventNameIndex[eventName] = callback;
return this;
}
};
}
};
그리고 평소처럼 사용합니다.
db.connection.query("SELECT * FROM `table` WHERE `id` = ? ", row_id)
.on('result', function (row) {
setData(row);
})
.on('error', function (err) {
callback({error: true, err: err});
});
언급URL : https://stackoverflow.com/questions/17015590/node-js-mysql-needing-persistent-connection
'programing' 카테고리의 다른 글
| 키코드 13은 어떤 키를 위한 것입니까? (0) | 2023.10.24 |
|---|---|
| AngularJS로 확장 및 축소 (0) | 2023.10.24 |
| JSON 웹 서비스에서 오류 상태를 반환하는 기존 방식이 있습니까? (0) | 2023.10.24 |
| Pure css 닫기 버튼 (0) | 2023.10.24 |
| Oracle/SQL: 쿼리 "SELECT * From records WHEROWNUM >= 5 ANDROWNUM <= 10" - 0개의 행을 반환하는 이유 (0) | 2023.10.19 |