?1?node.js簡介 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 原創(chuàng)者:文思
node.js:js版本的jvm
是一個基于Chrome JavaScript運行時建立的平臺, 用于方便地搭建響應(yīng)速度快、易于擴展的網(wǎng)絡(luò)應(yīng)用。 node.js使用事件驅(qū)動, 非阻塞I/O 模型而得以輕量和高效,非常適合在分布式設(shè)備上運行數(shù)據(jù)密集型的實時應(yīng)用。
node.js與java都是服務(wù)器語言,但是兩者存在很大區(qū)別:
(1)node.js比Java更快 : node.js開發(fā)快,運行的效率也算比較高,但是如果項目大了就容易亂,而且javascript不是靜態(tài)類型的語言,要到運行時才知道類型錯誤,java開發(fā)慢,但是如果項目大、復(fù)雜的話,用java就不容易亂,管理起來比node.js省
(2) node.js 前后端都采用Javascript
(3) node.js和Java EE——一種是解釋語言,一種是編譯語言
優(yōu)點:
node真正的亮點在于建設(shè)高性能,高擴展性的互聯(lián)網(wǎng)應(yīng)用——因為它能夠處理龐大的并且高吞吐量的并發(fā)連接,Node.js從來不是用于解決大規(guī)模計算問題而創(chuàng)建的。它的出現(xiàn)是為了解決大規(guī)模I/O的問題,項目需求中不包含CPU密集型操作,也不需要訪問任何阻塞的資源,那么你就可以利用的node.js的優(yōu)點:
RESTfulAPI
單線程:node.js可以在不新增額外線程的情況下,依然可以對任務(wù)進行并發(fā)處理(node.js是單線程的)。它通過事件輪詢(event loop)來實現(xiàn)并發(fā)操作,我們應(yīng)該要充分利用這一點(盡可能的避免阻塞操作,取而代之,多使用非阻塞操作)
非阻塞IO:阻塞調(diào)用是指調(diào)用結(jié)果返回之前,當前線程會被掛起。調(diào)用線程只有在得到結(jié)果之后才會返回。非阻塞調(diào)用指在不能立刻得到結(jié)果之前,該調(diào)用不會阻塞當前線程。
(你打電話問書店老板有沒有《分布式系統(tǒng)》這本書,你如果是阻塞式調(diào)用,你會一直把自己“掛起”,直到得到這本書有沒有的結(jié)果,如果是非阻塞式調(diào)用,你不管老板有沒有告訴你,你自己先一邊去玩了,當然你也要偶爾過幾分鐘check一下老板有沒有返回結(jié)果)
事件驅(qū)動:所謂事件驅(qū)動,簡單地說就是你點什么按鈕(即產(chǎn)生什么事件),電腦執(zhí)行什么操作(即調(diào)用什么函數(shù))
傳統(tǒng)的網(wǎng)絡(luò)服務(wù)技術(shù),是每個新增一個連接(請求)便生成一個新的線程,這個新的線程會占用系統(tǒng)內(nèi)存,最終會占掉所有的可用內(nèi)存。而node.js僅僅只運行在一個單線程中,使用非阻塞的異步I/O調(diào)用,所有連接都由該線程處理,在libuv的加分下,可以允許其支持數(shù)萬并發(fā)連接(全部掛在該線程的事件循環(huán)中)

node.js的應(yīng)用:

?2 基于nodeJS技術(shù)的前后端分離方案
對為何前后端分離的思考:
1 現(xiàn)有開發(fā)模式的適用場景?
2 前后端職責不清?
3 開發(fā)效率問題?
4 對前端發(fā)揮的局限?
5 更多...
在此之前,你需要知道什么是前后端分離?
傳統(tǒng)的物理層面前后端分離

1、所有用到的展現(xiàn)數(shù)據(jù)都是后端通過異步接口(AJAX/JSONP)的方式提供的,前端只管展現(xiàn)。WEB服務(wù)中,SPA(Single-page application)類占的比例很少。很多場景下還有同步/同步+異步混合的模式,SPA不能作為一種通用的解決方案。
2、現(xiàn)階段的SPA開發(fā)模式,接口通常是按照展現(xiàn)邏輯來提供的,有時候為了提高效率,后端會幫我們處理一些展現(xiàn)邏輯,這就意味著后端還是涉足了View層的工作,不是真正的前后端分離。
業(yè)務(wù)與職責層面的前后端分離
前端:負責View和Controller層。
后端:只負責Model層,業(yè)務(wù)處理/數(shù)據(jù)等。

非node.js中間層的架構(gòu)方案(比如采用Backbone,EmberJS, KnockoutJS, Angular框架):

但是,世上就怕但是二字:

各層職責重疊:
Client-side Model是Server-side?Model的加工
Client-side View跟Server-side是 不同層次的東西
Client-side的Controller跟Sever-side的Controller各搞各的
Client-side的Route但是Server-side可能沒有
性能問題:
渲染,取值都在客戶端進行,有性能的問題
在移動設(shè)備低速網(wǎng)路的體驗奇差無比
重用問題:
模版無法重用,造成維護上的麻煩與不一致
邏輯無法重用,前端的校驗后端仍須在做一次
路由無法重用,前端的路由在后端未必存在
跨終端問題:
業(yè)務(wù)太靠前,導(dǎo)致不同端重復(fù)實現(xiàn)
邏輯太靠前,造成維護上的不易
node.js在哪里,職責清晰的架構(gòu) + 前端范圍的擴展 =重新定義前后端基于node.js中間層分離方案

nodeJS作為中間層開發(fā)方的優(yōu)勢:
前端可以更加專注于視圖層,而讓更多的數(shù)據(jù)邏輯放在Node層處理
轉(zhuǎn)發(fā)數(shù)據(jù),串接服務(wù)
路由設(shè)計,控制邏輯
渲染頁面,體驗優(yōu)化
中間層帶來的性能問題,
在異步ajax轉(zhuǎn)成同步渲染過程中得到
平衡
更多的可能
node.js角色:中轉(zhuǎn)和前端控制

node.js作為中間層開發(fā)方案職責劃分:

還有疑惑?1為什么要多加NodeJS這一層?2多加一層,性能怎么樣?3多加一層,前端的工作量是不是增加了?4多加一層就多一層風險,怎么破?5 nodeJS什么都能做,為什么還要JAVA
1 (傳統(tǒng)MVC的模式進行開發(fā),這種模式嚴重阻礙了前端開發(fā)效率,也讓后端不能專注于業(yè)務(wù)開發(fā)),解決方案是讓前端能控制Controller層,但是如果在現(xiàn)有技術(shù)體系下很難做到,因為不可能讓所有前端都學java,nodeJS就能很好的解決這個問題
2 分層就涉及每層之間的通訊,肯定會有一定的性能損耗。但是合理的分層能讓職責清晰、也方便協(xié)作,會大大提高開發(fā)效率。分層帶來的損失,一定能在其他方面的收益彌補回來
3 相對于只切頁面/做demo,肯定是增加了一點,但是總體開發(fā)效率會提升很多
4 讀者自己思考吧,不要忘了百度
5 JAVA的基礎(chǔ)架構(gòu)已經(jīng)非常強大而且穩(wěn)定,而且更適合做現(xiàn)在架構(gòu)的事情
讓我們來看看先行者是怎么做的,淘寶基于nodeJS的前后端分離方案(引用自百度淘寶):
?

最上端是服務(wù)端,就是我們常說的后端。后端對于我們來說,就是一個接口的集合,
服務(wù)端提供各種各樣的接口供我們使用。因為有node層,也不用局限是什么形式的服務(wù)。對后端開發(fā)來說,他們只用關(guān)心業(yè)務(wù)代碼的接口實現(xiàn)。
服務(wù)端下面是node應(yīng)用。
node應(yīng)用中有一層Model Proxy與服務(wù)端進行通訊。這一層主要目前是抹平我們對不同接口的調(diào)用方式,封裝一些view層需要的Model。
node層還能直接輕松實現(xiàn)原來vmcommon,tms(淘寶內(nèi)容管理系統(tǒng))等需求。node層要使用什么框架由開發(fā)者自己決定。不過推薦使用express+xTemplate的組合,xTemplate能做到前后端公用。
怎么用node大家自己決定,但是令人興奮的是,我們終于可以使用Node輕松實現(xiàn)我們想要的輸出方式,比如::JSON/JSONP/RESTful/HTML/BigPipe/Comet/Socket/同步、異步。想怎么整就怎么整,完全根據(jù)你的場景決定。
瀏覽器層在我們這個架構(gòu)中沒有變化,也不希望因為引入node改變你以前在瀏覽器中開發(fā)的認知。引入node,只是把本該就前端控制的部分交由前端掌控。
場景舉例,其中淘寶基于node的首頁前后端分離優(yōu)化:
需求:
靜態(tài)資料展示,方便運營管理。更好的承載密集且龐大的流量
解決方案:
頁面緩存與定時刷新,返回緩存資料。nodeJS產(chǎn)出靜態(tài)頁面到CDN,定時刷新

淘寶基于node的詳情頁前后端分離優(yōu)化:
需求:
單日四億PV,頁面數(shù)據(jù)來自各個不同接口。為了不影響體驗,先產(chǎn)生頁面框架后。在發(fā)起多個異步請求取數(shù)據(jù)更新頁面。這些多出來的請求帶來的影響不小,尤其在無線端。
解決方案:
在nodeJS端使用Bigpiper技術(shù),合并請求,降低負擔,分批輸出,不影響體驗
接口性能優(yōu)化:
拆分大接口為獨立小接口,并發(fā)請求,串行=>并行,大幅縮短請求時間
部屬優(yōu)化:
一臺NodeJS對多臺JAVA服務(wù)器,合理的分配服務(wù)器帶來最大的產(chǎn)出
頁面渲染優(yōu)化:
前后端共享模版,首屏服務(wù)器渲染,次屏瀏覽器渲染,局部刷新瀏覽器渲染
單頁面應(yīng)用優(yōu)化:
前后端共享路由與模版。前端換頁,瀏覽器端渲染。直接輸入網(wǎng)址,服務(wù)器渲染
可靠性優(yōu)化:
單元測試,頁面測試,回歸測試,持續(xù)集成
開發(fā)過程中的設(shè)計思考點:
接口服務(wù)化
代碼模塊化
功能組件化
待續(xù)...