2014-11-05 272 views
1

對於Express.js而言,我是一個相當新的東西,其中一個讓我更加驚訝的事情是,比起其他服務器,比如Apache或IIS,Express.js服務器每次崩潰它會遇到未捕獲的異常或某個錯誤拒絕該網站並使其可供用戶訪問。一件可怕的事!防止Express.js崩潰

例如,我的應用程序由於數據庫表中的名稱更改而未定義變量而導致Javascript錯誤崩潰。

TypeError: Cannot call method 'replace' of undefined

這是不是這樣一個很好的例子,因爲我的網站移動到生產環境之前解決這個問題,但有時類似的錯誤可以採取哪些不應該引起服務器崩潰的一部分。

我希望看到一個錯誤頁面或只是在該特定頁面的錯誤,但關閉整個服務器這些事情聽起來很可怕。

Express error handlers似乎不足以達到此目的。

我一直在閱讀關於如何解決Node.js by using domains這種事情,但我沒有發現任何專門爲Express.js。

我發現的另一個選項,似乎並不是所有情況下都推薦的,它使用工具來永久運行一個進程,所以在崩潰之後,它會自行重啓。工具如Forever,UpstartMonit

你們在Express.js中如何處理這類問題?

+0

我們部署了我們的OpenShift服務器以及他們使用節點監控器(https://www.npmjs.org/package/supervisor)崩潰後,以保持我們的服務器了。你可能想看看這個包。 – Ben 2014-11-05 11:59:08

+0

@Ben聽起來像它的['nodemon'](https:// github。com/remy/nodemon),但它也會在服務器崩潰時重新啓動。 – Alvaro 2014-11-05 12:02:53

回答

3

Apache和nodejs之間的主要區別在於,Apache爲每個請求分配一個進程,而nodejs是單線程的,因此如果Apache中發生錯誤,那麼處理該請求的進程將崩潰,而其他進程將繼續工作,在nodejs中,而是唯一的線程關閉。

在我的項目中,我使用monit來檢查內存/ cpu(如果nodejs需要我的vps的很多資源,那麼monit會重新啓動nodejs)和daemontools以確保nodejs始終處於運行狀態。

1

我會推薦使用域以及羣集。文檔本身就有一個例子http://nodejs.org/api/domain.html。 expressjs https://www.npmjs.org/package/express-domain-middleware也有一些模塊。

因此,當發生這樣的錯誤時,使用域與羣集將幫助我們分離發生錯誤的位置的上下文,並且只會影響羣集中的單個工作者,我們應該記錄它們並在羣集中斷開該工作者並重新綁定它。然後,我們可以讀取日誌來修復需要在代碼中修復的錯誤。

0

我正面臨同樣的問題,我使用嘗試/緩存這樣固定。所以我創建了不同的路由文件,並在try/cache這樣的塊中包含了每個路由文件。

try{ 
    app.use('/api', require('./routes/user')) 
} 
catch(e) 
{ 
    console.log(e); 
} 


try{ 
    app.use('/api', require('./routes/customer')) 
} 
catch(e) 
{ 
    console.log(e); 
}