聊聊大規模NodeJS項目架構
- NodeJS異步IO原理淺析及優化方案
- NodeJS內存管理機制及內存優化
- 大規模Node站點結構原理分析
- 服務器集群管理與Node集群的應用
異步IO原理淺析
- 異步IO的是與非
- Node對異步IO的實現
- 幾個特殊的API
- 函數式編程在Node中的應用
- 常用的Node控制異步API的技術手段
異步IO的好處
- 首先,前端通過異步IO可以消除UI阻塞。
- 然后,如果是請求資源,請求A資源時間為M,請求B資源時間為N,如果是同步就需要M+N,如果是異步就需要MAX(M,N)。
- 隨著業務不斷擴大,引入分布式系統(一個業務拆分成多個小業務),時間會呈線性增加,同異步之間的差異會更加明顯。
IO是非常昂貴的,分布式IO更是昂貴的。 - NodeJS是適用于IO密集型,不適用于CPU密集型。為什么說node使用與IO密集型呢,因為IO密集型是異步的這樣的機制。有進有出就是IO。一下子進來500W請求,我交給異步去處理,處理完再通知我。
- JAVA和PHP也有異步,但是node天然就是異步,所以node更適用于游戲實時的這種,主播平臺,都用node,還有就是傳統代理,用node去處理,前端接收請求就少一點,阿里美團都會有中間層做處理。
- 底層知識:CPU時鐘周期,一個CPU時鐘周期(1s/2.8hz)Ghz;異步好,但并非所有的異步都好,阿姆達爾定律可以計算出通過改進計算機某一部分獲得的性能增益。Amdahl’s law 【1】【2】(Ws串行數);文件操作符,內核在進行文件IO操作時,通過文件操作符進行管理。node在o的那一個等待事件輪詢把文件操作符返回給你。
- 寫完以后去壓力測試,哪里有問題,給文件加密,并行就比串行快。
Node對異步IO的實現
- 完美的異步IO應該是應用程序發起的非阻塞調用,無需通過遍歷或喚醒等方式輪詢。
node
幾個特殊的API
- setTimeout和setInterval線程池不參與
- process.nextTick()實現類似setTimeout(function(){},0);每次調用放入隊列中,在下一輪循環中取出。(在任何其他I / O事件(包括定時器)后續觸發中觸發之前運行,效率要比setTimeout高,它會先執行)
- setimmediate();比process.nextTick()優先級低 上三者的區別
- Node如何實現一個sleep?
async test(){
console.log('1');
await sleep(1);
console.log('2');
}
sleep(time){
return new Promise((resolve)=>{setTimeout(()=>{resolve()},time)})
}
test()
- 哨兵變量
<script>
// 哨兵變量
var s = 0;
var result;
var arr = ['a.php','b.php','c.php'];
for(var i = arr.length-1; i >= 0; i--){
$.ajax({
url:arr[i],
success: function(){
s = s + 1;
if(s == 3){
alert(result);
}
}
})
}
// 函數式編程
$.ajax({
url: arr[0]
}).after()
</script>
函數式編程在node中的應用
- 高階函數:可以將函數作為參數或返回值,形成一種后續傳遞風格的結果接收方式,而不是單一的返回值形式,后續傳遞風格的程序將函數業務重點從返回值傳遞到回調函數中。
app.use(function(){//todo});
var emitter = new events.EventEmitter();
emitter.on(function(){//todo});
- 偏函數:指定部分參數形成一個新的定制函數的形式就是偏函數。Node中異步編程非常常見,我們通過哨兵變量會很容易產生業務的混亂。underscore,after變量
常用的Node控制異步技術手段
- step、wind(提供等待的異步庫)、Bigpipe、Q.js
- Async、Await
- Promise/Defferred是一種先執行異步調用,延遲傳遞的處理方式。Promise是高級接口,事件是低級接口。低級接口可以構建很多復雜場景,但高級接口一旦定義,就無法改變,不再有地接接口的靈活性,但對于解決問題非常有效。(then就是Deffered模式)
- 由于NodeV8的原因,目前還不支持協程。協程不是進程或線程,其執行過程更類似于子例程,或者說不帶返回值的函數調用。
- 一個程序可以包含多個協程,可以對比與一個進程包含多個線程,因而下面我們來比較協程和線程。我們知道多個線程相對獨立,有自己的上下文,切換受系統控制;而協程也相對獨立,有自己的上下文,但是其切換由自己控制,由當前協程切換到其它協程由當前協程來控制。
內存管理與優化
- V8垃圾回收機制
- 常見內存泄露問題
- 內存泄露分析
大規模Node站點結構原理分析
- 經典的MVC框架
- NET多層架構
- JavaWeb多層架構
Node集群的應用
- 預備上線
- 多線程
- PM2
- 服務器集群
預備上線
- 前端工程化搭載動態文件的MAP分析壓縮打包合并至CDN
- 單測、壓測性能分析工具發現Bug
- 編寫Nginx-conf實現負載均衡和反向代理
- PM2啟動應用程序小流量灰度上線,修復BUG
- 上線前不眠夜
多線程
- NodeJS的多核處理是用cluster模塊處理的。
PM2
- PM2是一個帶有負載均衡功能的Node應用的進程管理器。
- 當你要把你的獨立代碼利用全部的服務器上的所有CPU,并保證進程永遠都活著,0秒重載。
- 內建負載均衡(使用Node cluster集群模塊)
- 后臺運行
- 0秒停機重載
- 具有Ubuntu和CentOS的啟動腳本
- 停止不穩定的進程(避免無限循環)
- 控制臺檢測
- 提供HTTP API
- 遠程控制和實時的接口API(Nodejs模塊,允許和PM2進程管理器交互)
pm2