2013-11-26 4 views
43

, когда я использую узел mysql, с 12:00 до 2:00 появляется ошибка, когда TCP-соединение отключается сервером. Это полное сообщение:nodejs mysql Ошибка: соединение потеряно Сервер закрыл соединение

Error: Connection lost: The server closed the connection. 
at Protocol.end (/opt/node-v0.10.20-linux-x64/IM/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:920:16 
at process._tickCallback (node.js:415:13) 

Там есть solution. Однако, после того, как я попытаюсь таким образом, проблема также возникает. теперь я не знаю, как это сделать. Кто-нибудь справляется с этой проблемой?

Вот так, как я написал следовать решению:

var handleKFDisconnect = function() { 
    kfdb.on('error', function(err) { 
     if (!err.fatal) { 
      return; 
     } 
     if (err.code !== 'PROTOCOL_CONNECTION_LOST') { 
      console.log("PROTOCOL_CONNECTION_LOST"); 
      throw err; 
     } 
     log.error("The database is error:" + err.stack); 

     kfdb = mysql.createConnection(kf_config); 

     console.log("kfid"); 

     console.log(kfdb); 
     handleKFDisconnect(); 
    }); 
    }; 
    handleKFDisconnect(); 

ответ

93

Попробуйте использовать this code для обработки сервера разъединения:

var db_config = { 
    host: 'localhost', 
    user: 'root', 
    password: '', 
    database: 'example' 
}; 

var connection; 

function handleDisconnect() { 
    connection = mysql.createConnection(db_config); // Recreate the connection, since 
                // the old one cannot be reused. 

    connection.connect(function(err) {    // The server is either down 
    if(err) {          // or restarting (takes a while sometimes). 
     console.log('error when connecting to db:', err); 
     setTimeout(handleDisconnect, 2000); // We introduce a delay before attempting to reconnect, 
    }          // to avoid a hot loop, and to allow our node script to 
    });          // process asynchronous requests in the meantime. 
              // If you're also serving http, display a 503 error. 
    connection.on('error', function(err) { 
    console.log('db error', err); 
    if(err.code === 'PROTOCOL_CONNECTION_LOST') { // Connection to the MySQL server is usually 
     handleDisconnect();       // lost due to either server restart, or a 
    } else {          // connnection idle timeout (the wait_timeout 
     throw err;         // server variable configures this) 
    } 
    }); 
} 

handleDisconnect(); 

В своем коде я отсутствующая часть после connection = mysql.createConnection(db_config);

+0

Хорошо, я попробую это. но как я мог бы симулировать это siutation – jackieLin

+0

Зачем вам симулировать это? – CloudyMarble

+0

Теперь код работает. Объект базы данных не является нулевым, howerer, когда выбирает базу данных, он не может выполнять и останавливаться все время. Но у сера нет какой-либо ошибки! – jackieLin

22

Прагматическое решение состоит в том, чтобы заставить MySQL поддерживать связь живым:

setInterval(function() { 
    db.query('SELECT 1'); 
}, 5000); 

Я предпочитаю это решение для пула соединений и отключения связи, потому что он не требует структурирования вашего кода таким образом, чтобы он знал о наличии соединения. Выполнение запроса каждые 5 секунд гарантирует, что соединение останется в живых, а PROTOCOL_CONNECTION_LOST не произойдет.

Кроме того, этот способ гарантирует, что вы поддерживаете одно и то же соединение, в отличие от повторного подключения. Это важно. Подумайте, что произойдет, если ваш сценарий опирается на LAST_INSERT_ID(), а соединение mysql было сброшено, если вы не знаете об этом?

Однако это гарантирует, что время соединения (wait_timeout и interactive_timeout) не происходит. Как и ожидалось, он будет терпеть неудачу во всех остальных сценариях. Поэтому не забудьте обработать другие ошибки.

+0

Просто любопытно, куда бы вы положили этот запрос db? В нижней части узла nodejs правильно? Единственная проблема: я использую mysql для аутентификации пользователя один раз, а затем я храню свои данные во временном объекте пользователей для моей игры rpg. Я не знаю, почему я получил эту mysql закрытую ошибку случайным образом сегодня, хм. Я тоже правильно закрываю соединение и т. Д. –

+1

Вам необходимо подключиться к базе данных и отключиться по требованию. Это решение предназначено для служб, которые работают постоянно и постоянно используют соединение с базой данных. – Gajus

+0

Если это так, возможно ли, что у меня есть возможная утечка памяти или забыли применить db.end()? –

-1

Создание и уничтожение соединений в каждом запросе может быть сложным, я имел некоторые головные боли с миграции сервера, когда я решил установить MariaDB вместо MySQL. По какой-то причине в файле etc/my.cnf параметр wait_timeout имел значение по умолчанию 10 секунд (это приводит к тому, что персистентность не может быть реализована). Затем решение было установлено в 28800, это 8 часов. Ну, я надеюсь помочь кому-то с этой «гуэвонадой» ... извините за мой плохой английский.

Смежные вопросы