Node.JS生產(chǎn)環(huán)境實踐

最近生產(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)用程序能夠自動重新啟動

  1. 使用進(jìn)程管理器在應(yīng)用程序(和 Node)崩潰時將其重新啟動。
  2. 在操作系統(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)用),請使用 WinstonBunyan 之類的日志記錄庫,而不要使用 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:

  1. 高速緩存視圖模板。
  2. 高速緩存從 CSS 擴展生成的 CSS 文件。
  3. 生成簡短的錯誤消息。

測試表明僅僅這樣做就可以使應(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引擎

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評論 19 139
  • <<編程基礎(chǔ)-語言JavaScript.Nodejs.Mobile>>https://github.com/ope...
    燕京博士閱讀 1,091評論 0 2
  • topics: 1.The Node.js philosophy 2.The reactor pattern 3....
    宮若石閱讀 1,228評論 0 1
  • Node.js是目前非?;馃岬募夹g(shù),但是它的誕生經(jīng)歷卻很奇特。 眾所周知,在Netscape設(shè)計出JavaScri...
    w_zhuan閱讀 3,720評論 2 41
  • 我讀書非常不仔細(xì)+敷衍了事,如果讀進(jìn)去了恨不得熬夜囫圇吞完,如果開頭吸引不了我,就會立馬扔到角落里落灰。 那天路過...
    肖雨醬閱讀 244評論 3 2

友情鏈接更多精彩內(nèi)容