原文:Production best practices: performance and reliability
文章主要討論怎么提高Node工程的性能和可靠性,全文分為兩大部分:
- 開發(fā)的注意事項(xiàng)
- 部署的注意事項(xiàng)
開發(fā)
1. 使用gzip壓縮
Node有compression模塊;高并發(fā)場景下,最好借助代理(如:Nginx)實(shí)現(xiàn)gzip壓縮功能
2. 不要使用同步函數(shù)
高并發(fā)場景下,同步函數(shù)可能極大的影響系統(tǒng)的性能。
Node4.0+上的版本,--trace-sync-io
可打印出工程中使用到的同步函數(shù)的信息。
3. 正確打印日志
console.log() 或 console.err()
是同步函數(shù),它會(huì)阻塞后續(xù)程序的執(zhí)行,盡量少用。
debug模式下,采用模塊debug 可以借組環(huán)境變量,這樣在發(fā)布后就可以不輸出debug的log。
如果想記錄工程的流量或者API調(diào)用,可以采用winston 或者bunyan ,文章Comparing Winston and Bunyan Node.js Logging給出了兩者的對比。
4. 合理的處理異常
Node工程中出現(xiàn)沒有被捕獲的異常時(shí)服務(wù)會(huì)掛掉,所以首先要保證服務(wù)能自動(dòng)重啟,好在它的重啟比較快;另外可通過try catch
和promise
捕獲異常。
app.get('/search', function (req, res) {
// Simulating async operation
setImmediate(function () {
var jsonStr = req.query.params;
try {
var jsonObj = JSON.parse(jsonStr);
res.send('Success');
} catch (e) {
res.status(400).send('Invalid JSON string');
}
});
});
app.get('/', function (req, res, next) {
// do some sync stuff
queryDb()
.then(function (data) {
// handle data
return makeCsv(data)
})
.then(function (csv) {
// handle csv
})
.catch(next);
});
不要捕獲uncaughtException
事件,服務(wù)該掛掉就掛掉,否者可能引入不必要的問題。
部署
1. 把NODE_ENV
設(shè)置為production
NODE_ENV為production時(shí),Express會(huì)緩存視圖模板、css文件,產(chǎn)生更少的錯(cuò)誤信息;測試The drastic effects of omitting NODE_ENV in your Express.js applications表明啟用了cache,性能提升1/3!
2. 確認(rèn)服務(wù)能自動(dòng)重啟
借助pm2、forever等工具實(shí)現(xiàn)自動(dòng)重啟;并且要實(shí)現(xiàn)開機(jī)時(shí)的服務(wù)自啟動(dòng)。
3. 服務(wù)運(yùn)行在cluster模式
多核的服務(wù)器,通過cluster可以提升服務(wù)性能。
4. 緩存請求結(jié)果
可以通過Nginx實(shí)現(xiàn)緩存,提高同一資源多次請求的速度。
5. 使用負(fù)載均衡
負(fù)載均衡可以提高集群服務(wù)的數(shù)量
6. 使用反向代理
和工程關(guān)聯(lián)不大的靜態(tài)資源的請求,可以通過Nginx的反應(yīng)代理實(shí)現(xiàn)。