2013-12-19 75 views
2

我有快速的錯誤處理middlware試圖捕獲所有傳入的錯誤:如何確保Node.js在MonogDB連接斷開後繼續運行?

app.use(function(err, req, res, next){ 
    console.error(err.stack); 
    res.status(500); 
    res.render('500.jade'); 
}); 

但由於某些原因,每當我關閉mongod過程中,我的應用程序崩潰,並顯示以下堆棧跟蹤:

Error: failed to connect to [localhost:27017] 
    at null.<anonymous> (/<hidden>/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/server.js:540:74) 
    at EventEmitter.emit (events.js:106:17) 
    at null.<anonymous> (/<hidden>/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/connection_pool.js:140:15) 
    at EventEmitter.emit (events.js:98:17) 
    at Socket.<anonymous> (/<hidden>/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/connection.js:478:10) 
    at Socket.EventEmitter.emit (events.js:95:17) 
    at net.js:441:14 
    at process._tickCallback (node.js:415:13) 

Process finished with exit code 8 

我已經使用以下配置試過了,但它並沒有幫助我:

var options = { 
    server:{ 
    auto_reconnect: true, 
     poolSize: 10, 
     socketOptions:{ 
     keepAlive: 1 
    } 
    }, 
    db: { 
    numberOfRetries: 10, 
    retryMiliSeconds: 1000 
    } 
} 

mongoose.connect(config.db, options); 

有人可能會問「爲什麼你希望你的應用程序能夠在沒有數據庫連接的情況下運行?「。我不希望它崩潰並重新啓動。 Supervisor和Forever模塊在嘗試一定次數後似乎停止嘗試重新連接,從而使應用程序處於崩潰狀態。

理想情況下,當MongoDB崩潰時,我想向用戶顯示一個500.jade錯誤頁面,同時服務器應該每隔10秒嘗試重新連接一次數據庫。重新連接後,恢復所有正常操作。

編輯:下面發佈的解決方案都沒有爲我工作,除了域。

回答

3

嘗試初始化DB在domain,這將趕上錯誤不會崩潰

var d = require('domain').create(); 

d.on('error', function(er) { 
    console.log('Oh no, something wrong with DB'); 
}); 

d.run(function() { 
    mongoose.connect(config.db, options); 
}); 

它通常是一個好主意,讓服務器重啓時的東西崩潰,但你已經意識到這一點,想要避免它,包裝任何失敗的領域是做到這一點的方式。

+1

太棒了,我從來沒有使用過Node.js域名。學會了今天的新事物;)。漂亮而優雅的解決方案 –

+1

@TwilightPonyInc。 - 不久前添加的域,仍然被認爲有些不穩定,但是我一直在使用與Cassandra類似的DB在生產中一段時間​​,並且從未遇到過問題,如果數據庫失敗,節點繼續運行,當數據庫再次可用時,就像沒有發生過任何事情,我到處尋找泄漏,對我來說似乎很好。我沒有真正嘗試過Mongo,但它原則上應該是一樣的。 – adeneo

+0

只是不要開始在域中包裝內部節點進程,因爲這可能會導致問題和嚴重泄漏。 – adeneo

0

當連接丟失時,MongoDB驅動程序發出「關閉」事件。您可以點擊此事件並將數據庫標記爲不可用,並基於此編寫任何邏輯。

db.on('close', function() { 
    // handle the disconnect 
    dbAvailable = false; 
}); 

我已經得到了,如果你有興趣處理這個小NPM模塊:https://npmjs.org/package/mongoconnect

+0

我可以通過做一個簡單的'console.log()'來成功捕獲這個事件,但是在大約1秒之後,服務器崩潰了'throw er; //未處理「錯誤」事件「。我在這裏做錯了什麼? (使用Express和Mongoose的最新版本)。類似於:http://stackoverflow.com/questions/17809285/mongoose-times-out-and-throws-exception –

5

這是我做處理蒙戈失敗 - 將其添加爲中間件。它也會嘗試重新連接。

// Handler in case Mongo goes down 
app.use(function(req, res, next) { 
    // We lost connection! 
    if (1 !== mongoose.connection.readyState) { 

    // Reconnect if we can 
    mongoose.connect(config.db, options); 
    res.status(503); 
    throw new Error('Mongo not available'); 
    } 
    next(); 

}); 

此假設你有一個標準的50倍錯誤處理的地方,會顯示一個漂亮的頁面給用戶。

重新連接用於下一個用戶/頁面加載,以檢查它是否備份。工作很好。

相關問題