最近生產(chǎn)環(huán)境用Node.js的項目越來越多,與Java\PHP傳統(tǒng)技術(shù)還是有很多的不同。因此在此進(jìn)行總結(jié)一下。
部署
使用集群
Node.JS是單線程,并且有最大內(nèi)存使用限制1.5G(參考:node wiki)。因此無法自動充分利用多CPU核優(yōu)勢。
注:64位系統(tǒng)1.4G,32位則僅分配0.7G
但是Node.js有很多強大的進(jìn)程管理器。比較推薦使用的是pm2,使用起來非常方便。通過指定pm2參數(shù)
...
"instances": 4, //進(jìn)程數(shù)量 0為參考cpu核數(shù)量,-1是cpu核數(shù)-1
"exec_mode": "cluster",
...
可以讓Node.JS分為多個子進(jìn)程運行。另外pm2還有很多其他的優(yōu)點,具體參考pm2官方文檔
確保應(yīng)用程序能夠自動重新啟動
- 使用進(jìn)程管理器在應(yīng)用程序(和 Node)崩潰時將其重新啟動。
- 在操作系統(tǒng)崩潰時,使用操作系統(tǒng)提供的初始化系統(tǒng)重新啟動進(jìn)程管理器。還可以在沒有進(jìn)程管理器的情況下使用初始化系統(tǒng)。
使用pm2能夠在應(yīng)用程序崩潰后自動將應(yīng)用程序拉起。具體參考pm2官方文檔
使用反向代理
使用nginx做nodejs的代理,并提供靜態(tài)文件服務(wù)。因為nginx是一個專門針對靜態(tài)文件服務(wù)做過優(yōu)化的開源Web服務(wù)器,這樣可以讓Node高效處理動態(tài)內(nèi)容服務(wù)。
使用gzip壓縮
通過gzip壓縮,有助于顯著降低響應(yīng)主體的大小,從而提高Web應(yīng)用程序的速度。在生產(chǎn)環(huán)境中的大流量網(wǎng)站,實施壓縮的最佳位置是在反向代理層級。
程序設(shè)計
不要在web服務(wù)器里執(zhí)行重型任務(wù)
Node服務(wù)器擅長處理IO密集型任務(wù),不擅長CPU密集型任務(wù)。所以提升性能的關(guān)鍵是保證Node.js的事件處理線程不被阻塞,需要花長時間完成的任務(wù)交由其他節(jié)點服務(wù)器或單獨進(jìn)程進(jìn)行處理
不使用同步函數(shù)
同步函數(shù)會阻止執(zhí)行進(jìn)程的運行,直至返回。雖然 Node 和許多模塊提供函數(shù)的同步和異步版本,但是在生產(chǎn)環(huán)境中請始終使用異步版本。只有在初始啟動時才適合使用同步函數(shù)。
正確進(jìn)行日志記錄
一般而言,從應(yīng)用程序進(jìn)行日志記錄有兩個原因:出于調(diào)試目的和出于記錄應(yīng)用程序活動目的(基本上就是除調(diào)試以外的其他所有事項)。通過使用 console.log()
或 console.err()在終端上顯示日志消息是開發(fā)過程中的常見做法。但是,如果目標(biāo)是終端或文件,這些函數(shù)就是同步的,因此,除非要將輸出通過管道傳到另一個程序,否則上述函數(shù)就不適合用于生產(chǎn)環(huán)境。
如果要對應(yīng)用程序活動進(jìn)行日志記錄(例如,跟蹤流量或 API 調(diào)用),請使用 Winston 或 Bunyan 之類的日志記錄庫,而不要使用 console.log()
。要了解這兩個庫的詳細(xì)對比,請參閱 StrongLoop 博客帖子 Comparing Winston and Bunyan Node.js Logging。
正確處理異常
Node 將“error-first 回調(diào)”約定用于從異步函數(shù)返回錯誤,回調(diào)函數(shù)的第一個參數(shù)是錯誤對象,后續(xù)參數(shù)中包含結(jié)果數(shù)據(jù)。為了表明沒有錯誤,可將 null 值作為第一個參數(shù)傳遞?;卣{(diào)函數(shù)必須相應(yīng)地遵循“error-first”回調(diào)約定,以便有意義地處理錯誤。
在Express中,最佳做法是使用next()函數(shù),通過中間件鏈來傳播錯誤。最后通過error handler來處理。
// error handler
app.use((err, req, res, next) => {
// render the error page
errorLogger.error('server error:' + err);
res.status(err.status || 500);
res.send('error');
});
將 NODE_ENV 設(shè)置為“production”
NODE_ENV 環(huán)境變量指定運行應(yīng)用程序的環(huán)境(通常是開發(fā)或者生產(chǎn)環(huán)境)。為了改進(jìn)性能,最簡單的方法是將 NODE_ENV 設(shè)置為“production”。
將 NODE_ENV 設(shè)置為“production”會使 Express:
- 高速緩存視圖模板。
- 高速緩存從 CSS 擴展生成的 CSS 文件。
- 生成簡短的錯誤消息。
測試表明僅僅這樣做就可以使應(yīng)用程序性能提高 3 倍多!
性能調(diào)優(yōu)
Node.JS的性能調(diào)優(yōu)需要深入了解Node.JS的垃圾回收與內(nèi)存管理機制。
Node.JS構(gòu)建于V8引擎智商,因此先了解v8引擎的內(nèi)存管理機制,再研究底層原理,最后再研究Node開發(fā)中的內(nèi)存管理與優(yōu)化。
v8引擎