一、先後端耦合太緊密,中間加一層node,還要給前端裝一些亂七八糟的東西 java啥的服務環境。還有後臺返回接口的時候無論前端需不須要那些接口一塊兒返回,其實只用到1~2 條數據。原本ajax就很是消耗時的事,就用其中一條,用node作一層中間層處理把沒用的接口剔除掉。javascript
二、好比:一個10天項目,後臺開發6天,前臺2天,測試2天。後臺開發時,沒有接口,前端得等着後臺的接口,若是後臺某種狀況推遲了一天,前端就1天開發,測試要2天,確定前端開發不完。使用node咱們能夠並行開發,提升開發效率。前端
三、proxy 代理層 java->node 前端->node 這種狀況叫BFF,後臺是沒有跨域的。作了一層中間代理,能夠本身控制路由,前端請求發給node,就不會出現跨域的問題。node socket io 實時通信。java
四、node容錯,性能難作。node
一些底層知識linux
一、nginx
CPU是鍾週期:1/CPU主頻->1s/3.1GHzweb
一級CPU是鍾週期:3.5GHz 1/3.5*3 io時間ajax
二、算法
p是並行系統鐘的處理器數量;編程
f=ws/w爲串行部分的比例;
咱們分佈到其餘機器裏,每一個機器都用一樣的代碼。網絡要請求這文件,就比較慢 整個時間就比較長。
並非全部的全部並行的好,也並很多全部串行就好,分狀況。系統會自動根據狀況來判斷使用並行仍是串行。
三、操做系統對計算機進行來抽象,將全部輸入輸出設備抽象爲文件。內核在進行文件I/O操做時,經過文件描述符進行管理。應用程序若是須要進行I/O須要打開文件描述符,在進行文件和數據的讀寫。異步IO不帶數據直接返回,要獲取數據還須要經過文件描述符再次讀取。
好比銀行,每次計算價格,java是多線程能夠處理多個任務,而Nodejs是單線程用異步不停的寫,寫發上也很是複雜。能夠有框架處理單線程問題,可是性能上仍是不如java。
完美的異步IO應該是應用程序發起阻塞調用,無需經過便利或者事件幻想等方式輪詢。
前端的event loop跟node event loop不同,前端比node event loop還要複雜一些。node程序進來不停的轉,就等於咱們把米放到電飯煲裏,定好時間,咱們去忙別的,等他作好以後,會提示,已經作好了。
一、setTimeout和setInterval線程池不參與
二、process.nextTick()實現相似setTimeout(function(){},0);每次調用放入隊列中,在下一輪循環中取出。
三、setImmediate();比provess.nextTick()優先級低
四、Node如何實現一個Sleep?
async function test(){ console.log('hello'); await seelp(1000); console.log('word'); } function seelp(time){ return new Promise(resolve=>setTimeout(resolve,time)) } test()
一、高階函數:能夠將函數做爲輸入或者返回值,造成一種後續傳遞風格的結果接受方式,而非單一的返回值造成。後續傳遞風格的程序將函數業務重點從返回值傳遞到回調函數中。
app.use(function(){ //todo }) var emitter = new event.eventEmitter; emitter.on(function(){ //todo })
二、偏函數:指定部分參數產生一個新的定製函數的形式就是偏函數。node中異步編程很是常見,咱們經過哨兵變量會很容易形成業務的混亂。underscore,after變量。
一、step、wind(提供等待的異步庫)、bigpipe、Q.js
二、Async、Await
三、Promise/Defferred是一種先執行異步調用,延遲傳遞的處理方式。Promise是高級接口,事件是低級接口。低級接口能夠構建更多複雜的場景,高級接口一旦定義,不太容易變化,再也不有低級接口的靈活性,但對於解決問題很是有效。
四、因爲Node基於V8的緣由,目前還不支持協程。協程不是進程或線程,其執行過程更相似於子例程,或者說不帶返回值的函數調用。
一個程序能夠包含多個協程,能夠對比一個進程包含多個線程。來比較協程和線程。咱們知道多個線程相對獨立,有本身的上下文,切換受系統控制;而協程也相對獨立,有本身的上下文,可是其切換由本身控制,由當前協程切換到其餘協程有當前協程來控制。
node使用javascript在服務端操做大內存對象受到了必定的限制,64位系統下約爲1.4GB,32位系統是0.7GB
process.memoryUsage->rss、heaptTotal、heapUsed
V8的垃圾回收策略主要基於分代式垃圾回收機制。在自動垃圾回收的演變過程當中,人們發現沒有一種垃圾回收算法可以勝任全部場景。V8內存分爲新生代和老生代。新生代爲存活時間較短對象,老聖代爲存活時間較長的對象。
在分帶基礎上,新生代的對象主要經過Scavenge算法進行垃圾回收,在具體實現時主要採用cheney算法,cheney算法是一種採用複製的方法實現的垃圾回收算法。它將內存一分爲二,每個空間稱爲semispace。這兩個semispace中一個處於使用,一個處於閒置。處於使用的稱之爲From,檢查From存活對象複製到To。非存活被釋放。而後互換位置。再次進行回收,發現被回收過直接晉升,或者發現To空間已經使用來超過25%。他的缺點只能使用堆內存的一半,這是一個典型的空間換時間的辦法,可是新生代生命週期較短,偏偏就適合這個算法。
老生代空間生成完成確定要有東西管理它,就有來mark-sweep和mark-compact
V8老生代主要採用mark-sweep和mark-compact,在使用Scavenge不合適。一個是對象較多須要賦值量太大並且仍是沒能解決空間問題。Mark-Sweep是標記清除,標記那些死亡的對象,而後清除。可是清除事後出現內存不連續的狀況,全部咱們要使用Mark-Compact,他是基於mark-sweep演變而來的,它現將活着的對象移到一邊,移動完成後,直接清理邊界外的內存。當CPU空間不足的時候會很是高效。V8還引入來延遲處理,增量處理,並計劃引入並標記處理。
一、無限制增加的數組
二、無限制設置屬性和值
三、任何模塊內的私有變量和方法均是永駐內存的a=null
四、大循環,無GC(垃圾回收機制)機會
node-inspector
console.log("Server PID",process.pid);
sodu node --inspect app.js
whie true;do curl "http:localhost:1337/";done
top -pid 2322
model-view-Controller
javaweb多層架構
一、前端工程化的搭載動態文件的MAP分析壓縮打包合併至CDN
二、單側、壓力測試、性能分析工具發現Bug
三、編寫nginx-conf實現負載均衡和反向代理
四、PM2啓動應用生序小流量灰度上線,修復Bug
五、上線前的不眠夜、你見過凌晨5點的北京麼?
多線程
一、master進程均爲主進程,Fork能夠創造主進程。
二、經過child_process能夠和NET模塊組合,能夠建立多個線程並監聽統一端口。經過句柄傳遞完成自動啓動、發射自殺信號、限量重啓、負載均衡。
三、node默認的機制是採用操做系統的搶佔式策略。閒着的進程爭搶任務,可是會形成CPU閒置的IO暫時並未閒置。Node後來引入來Round-Robin機制,也叫輪詢調度。主進程接受任務,在發。
四、每一個子進程作好本身的事,而後經過進程間通訊來將他們連接起來。這符合Unix的設計理念,每一個進程只作一件事,並作好。將福啊分解爲簡單,將簡單組合程強大。
pm2是一個自帶負載均衡功能的node應用的進程管理器。
當你要把你的獨立代碼利用所有的服務器上的全部CPU,並保證進程永遠活着,0秒重載。
一、內建負載均衡(使用node cluster集羣模塊)
二、後臺運行
三、0秒停機重仔
四、具備Ubuntu和CentOS的啓動腳本
五、中止不穩定的進程(避免無限循環)
六、控制檯檢測
七、提供HTTP API
八、遠程控制和實時的接口API(Nodejs 模塊,容許和PM2進程管理交互)
測試過Nodejs v0.11 v0.10 v0.8版本,兼容CoffeeScript,基於linux和MacOs
我以前是前端連java感受還能夠,若是我中間加一層node,是否是就變慢了呢,並非,首先java跟node在一樣一個機房他倆請求的時間被嚴格限制在1ms(毫秒),甚至一些團隊100ms已經頂天了,300ms服務確定有問題。用戶確定沒法感知的,node和java走了一次http,會有3次握手,即便是毫秒也是一次浪費,node和java 走的是Linux Virtual Server(Linux虛擬服務器)通訊。