Постоянно падает сервер на node.js?

//-----------------------------------------------
var mysql = require('mysql');
var connection = mysql.createConnection({
    host     : 'localhost',
    user     : 'track',
    password : '***********',
	database :'TRACK'
});

//----------------------------------------------
var net = require('net');

var HOST = '***.***.**.**';
var PORT = 8888;


net.createServer(function(sock) {
    
    sock.on('data', function(data) {
	    var date = new Date();
		var sDate= date.getSeconds()+":"+date.getMinutes()+":"+date.getHours()+" "+date.getDate()+"."+(date.getMonth()+1)+"."+date.getFullYear();
   	
       
        console.log('DATA :' + sDate +  " : " + sock.remoteAddress + ': ' + data);
        sock.write('You said "' + data + '"');
        
		var sSQL="insert into `track` (`text`) values ('" + data + "')";
		connection.query(sSQL, function(error, result, fields){   
	
		});
    });
    
    sock.on('close', function(data) {
      //  console.log('CLOSED: ' + sock.remoteAddress +' '+ sock.remotePort);
    });
    
}).listen(PORT, HOST);

console.log('Server listening on ' + HOST +':'+ PORT);


Вот такой код сервера, запускаю через
screen node server.js

Отрабатывает 10- 20 часов и падает.
Помогите разобраться в чём причина.
  • Вопрос задан
  • 10481 просмотр
Решения вопроса 1
@XProx Автор вопроса
Кодер
помог модуль forever
var forever = require('forever-monitor');
//------------------------------------------------------------
var child = new (forever.Monitor)('/var/www/nj/server.js',
{
'minUptime': 50,
'spinSleepTime': 10,
'logFile': '/var/www/nj/log_fr.txt', // Path to log output from forever process (when daemonized)
'outFile': '/var/www/nj/out_fr.txt', // Path to log output from child stdout
'errFile': '/var/www/nj/err_fr.txt' // Path to log output from child stderr
}
Ответ написан
Пригласить эксперта
Ответы на вопрос 5
Staltec
@Staltec
Node.js разработчик
Могу предположить, что процесс падает из-за разрыва соединения по таймауту со стороны mySQL если длительное время не было активности на подключении. В этом случае исключение имеет следующий вид:
Error: Connection lost: The server closed the connection.
    at Protocol.end (*path_to_project*/node_modules/mysql/lib/protocol/Protocol.js:103:13)
    at Socket.<anonymous> (*path_to_project*/node_modules/mysql/lib/Connection.js:88:28)
    at Socket.emit (events.js:117:20)
    at _stream_readable.js:944:16
    at process._tickCallback (node.js:442:13)


Лечится выставлением таймаута для подключения к mySQL вручную:
mysqlConnection.query("SET SESSION wait_timeout = 604800"); // 7 days timeout

А вообще конечно надо запускать node-процесс под супервайзером (pm2, forever, supervisor) и заворачивать поток ошибок в соответствующий error.log. Там сразу будет видно с каким исключением завалился процесс. В противном случае с такими вопросами обращайтесь на битву экстрасенсов.
Ответ написан
MarcusAurelius
@MarcusAurelius Куратор тега Node.js
автор Impress Application Server для Node.js
Вообще нужно логировать вывод, он же не просто падает, а что-то говорит, наверняка, или ошибка или память закончилась. Скорее всего у вас отпадает connection и следующие запросы не проходят, нужно сделать переподключение, вынесите соединение в function openConnection и повесьте событие, примерно так connection.on('error', function(err) { if (err.code === 'PROTOCOL_CONNECTION_LOST') openConnection(); });
И пожалуйста, не клейте SQL из строк, используйте параметры запросов. Тут вот моя библиотечка старая, в ней примеры и дополнительные удобства: https://github.com/tshemsedinov/node-mysql-utilities
Ответ написан
web-verzus-team
@web-verzus-team
Full Stack Developer
Еще как вариант: создавать не соединение, а пул
const pool = mysql.createPool({
    host     : 'localhost',
    user     : 'root',
    password : '',
    database : 'chat'
});

а затем "получаем" соединение:
pool.getConnection(function(err, connection) {
	if(err) {
		console.log(err);
	}
	let sql = "SELECT * FROM `table`";
	connection.query(sql, [], function(err, results) {
		connection.release(); // always put connection back in pool after last query
		console.log(results);
		if(err) {
			console.log(err);
		}
	});
});
Ответ написан
@AlSutman
Я решил проблему след образом: поставил pm2, это менеджер процессов, и стартанул свое приложение через pm2 start npm -- start и каждый раз, когда что-то падает, он просто перезапускается, еще ни разу не подвел, очень рекомендую.
Ответ написан
Комментировать
Aziz87
@Aziz87
80LVL
Делайте собственную функцию для запросов. 
Если запрос не прошел - Пробуем подключиться к базе еще раз и затем заново выполнить запрос.
Если вторая попытка тоже не прошла - возвращаем пустой ответ, чтобы не было ошибок на стороне сервера и он не крахнулся.


let mysqldb = require("mysql");
let mysql = null;

function connect(callback=null){
    console.log("MYSQL TAKE CONNECT");
    mysql=mysqldb.createConnection({host: "localhost", user: "*", password: "*", database:"*"});
    mysql.on('error', function(err) {
      console.log("---" +err.message);
      console.log("---" +err.code);
    });
  if(callback)setTimeout(callback,100);
}

connect();//Первичное подключение


//Функция для запросов к базе
function my_mysql_query_function(q, paramas, callback=null, reconnect=true){
//Пробуем сделать запрос
    mysql.query(q,paramas,function(err,rows){
      if(err){//Запрос не прошел
        console.log("mysql_query failed! calling again...");
        if(reconnect)//Если разрешено  повторить попытку
          connect(function(){ //Переподключаемся к базой
           my_mysql_query_function(q,params,callback,false);//Повторяем заново с меткой false == больше не пробовать 
          });
        else callback([]); //Если нельзя больше пробовать подключаться - возвращаем пустой массив ответа
      }else{
        if(callback) callback(rows); // если запрос успешный то возвращаем массив ответа
      }
    });
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы