2013-11-26 226 views
43

當我使用節點mysql時,在服務器關閉TCP連接的12:00至2:00之間出現錯誤。這是一個完整的消息: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

現在的代碼是工作。數據庫對象不爲null,但選擇數據庫時,它不能執行並始終停止。但服務器不顯示任何錯誤! – jackieLin

22

一個實用的解決方案是強制MySQL保持連接活着:

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

我更喜歡這種解決方案連接池和處理斷開連接,因爲它不需要以知道連接存在的方式來構造您的代碼。每5秒進行一次查詢可確保連接保持活動狀態,並且不會發生PROTOCOL_CONNECTION_LOST

此外,此方法可確保您保持相同的連接存活,而不是重新連接。這個很重要。考慮一下如果你的腳本依賴於LAST_INSERT_ID()和mysql連接在你沒有意識到的情況下被重置會發生什麼?

但是,這隻能確保連接超時(wait_timeoutinteractive_timeout)不會發生。如預期的那樣,在所有其他情況下,它將失敗。因此,請確保處理其他錯誤。

+0

只是好奇,你會把那個數據庫查詢放在哪裏?在nodejs服務器的底部?唯一的問題是,我只使用mysql來驗證用戶身份,然後將他們的數據存儲在我的RPG遊戲的臨時用戶對象中。我不知道爲什麼我今天隨機得到這個mysql關閉的錯誤,嗯。我正在關閉連接,等等。 –

+1

您應該連接到數據庫並根據需要斷開連接。此解決方案適用於連續運行並始終利用數據庫連接的服務。 – Gajus

+0

如果是這樣的話,是否有可能發生內存泄漏或忘記應用db.end()? –

-1

創建和銷燬在每個查詢的連接,也許複雜的,我遇到了一些麻煩與服務器遷移時,我決定安裝MariaDB的,而不是MySQL的。出於某種原因,在文件etc/my.cnf中,參數wait_timeout的默認值爲10秒(這導致無法實現持久性)。然後,解決方案將其設置爲28800,即8小時。那麼,我希望能幫助這個「güevonada」的人......請原諒我的英文不好。

相關問題