優(yōu)缺點及適用場景討論

概述:
  NodeJS宣稱其目標(biāo)是“旨在提供一種簡單的構(gòu)建可伸縮網(wǎng)絡(luò)程序的方法”,那么它的出現(xiàn)是為了解決什么問題呢,它有什么優(yōu)缺點以及它適用于什么場景呢砾莱?
  本文就個人使用經(jīng)驗對這些問題進(jìn)行探討槽片。
一. NodeJS的特點
  我們先來看看NodeJS官網(wǎng)上的介紹:
  Node.js is a platform built on Chrome's JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.
  其特點為:
  1. 它是一個Javascript運(yùn)行環(huán)境
  2. 依賴于Chrome V8引擎進(jìn)行代碼解釋
  3. 事件驅(qū)動
  4. 非阻塞I/O
  5. 輕量、可伸縮福荸,適于實時數(shù)據(jù)交互應(yīng)用
  6. 單進(jìn)程蕴坪,單線程
二. NodeJS帶來的對系統(tǒng)瓶頸的解決方案
  它的出現(xiàn)確實能為我們解決現(xiàn)實當(dāng)中系統(tǒng)瓶頸提供了新的思路和方案,下面我們看看它能解決什么問題
  1. 并發(fā)連接
  舉個例子敬锐,想象一個場景背传,我們在銀行排隊辦理業(yè)務(wù),我們看看下面兩個模型
 √ǘ帷(1)系統(tǒng)線程模型:
  
  這種模型的問題顯而易見径玖,服務(wù)端只有一個線程,并發(fā)請求(用戶)到達(dá)只能處理一個颤介,其余的要先等待梳星,這就是阻塞,正在享受服務(wù)的請求阻塞后面的請求了
 」龆洹(2)多線程冤灾、線程池模型:
  
  這個模型已經(jīng)比上一個有所進(jìn)步,它調(diào)節(jié)服務(wù)端線程的數(shù)量來提高對并發(fā)請求的接收和響應(yīng)辕近,但并發(fā)量高的時候瞳购,請求仍然需要等待,它有個更嚴(yán)重的問題:
  回到代碼層面上來講亏推,我們看看客戶端請求與服務(wù)端通訊的過程:
  
  服務(wù)端與客戶端每建立一個連接学赛,都要為這個連接分配一套配套的資源,主要體現(xiàn)為系統(tǒng)內(nèi)存資源吞杭,以PHP為例盏浇,維護(hù)一個連接可能需要20M的內(nèi)存
  這就是為什么一般并發(fā)量一大,就需要多開服務(wù)器
  那么NodeJS是怎么解決這個問題的呢芽狗?
  我們來看另外一個模型绢掰,想象一下我們在快餐店點餐吃飯的場景
  (3)異步、事件驅(qū)動模型
  
  我們同樣是要發(fā)起請求滴劲,等待服務(wù)器端響應(yīng)攻晒;但是與銀行例子不同的是,這次我們點完餐后拿到了一個號碼班挖,
  拿到號碼鲁捏,我們往往會在位置上等待,而在我們后面的請求會繼續(xù)得到處理萧芙,同樣是拿了一個號碼然后到一旁等待给梅,接待員能一直進(jìn)行處理。
  等到飯菜做號了双揪,會喊號碼动羽,我們拿到了自己的飯菜,進(jìn)行后續(xù)的處理(吃飯)
  這個喊號碼的動作在NodeJS中叫做回調(diào)(Callback)渔期,能在事件(燒菜运吓,I/O)處理完成后繼續(xù)執(zhí)行后面的邏輯(吃飯),
  這體現(xiàn)了NodeJS的顯著特點疯趟,異步機(jī)制拘哨、事件驅(qū)動
  整個過程沒有阻塞新用戶的連接(點餐),也不需要維護(hù)已經(jīng)點餐的用戶與廚師的連接
  基于這樣的機(jī)制迅办,理論上陸續(xù)有用戶請求連接宅静,NodeJS都可以進(jìn)行響應(yīng),因此NodeJS能支持比Java站欺、PHP程序更高的并發(fā)量
  雖然維護(hù)事件隊列也需要成本姨夹,再由于NodeJS是單線程,事件隊列越長矾策,得到響應(yīng)的時間就越長磷账,并發(fā)量上去還是會力不從心
  
  總結(jié)一下NodeJS是怎么解決并發(fā)連接這個問題的:
  更改連接到服務(wù)器的方式,每個連接發(fā)射(emit)一個在NodeJS引擎進(jìn)程中運(yùn)行的事件(Event)贾虽,放進(jìn)事件隊列當(dāng)中逃糟,
  而不是為每個連接生成一個新的OS線程(并為其分配一些配套內(nèi)存)
  2. I/O阻塞
  NodeJS解決的另外一個問題是I/O阻塞,看看這樣的業(yè)務(wù)場景:需要從多個數(shù)據(jù)源拉取數(shù)據(jù)蓬豁,然后進(jìn)行處理
 〈卵省(1)串行獲取數(shù)據(jù),這是我們一般的解決方案地粪,以PHP為例
  
  假如獲取profile和timeline操作各需要1S取募,那么串行獲取就需要2S
  (2)NodeJS非阻塞I/O蟆技,發(fā)射/監(jiān)聽事件來控制執(zhí)行過程
  
  NodeJS遇到I/O事件會創(chuàng)建一個線程去執(zhí)行玩敏,然后主線程會繼續(xù)往下執(zhí)行的斗忌,
  因此,拿profile的動作觸發(fā)一個I/O事件旺聚,馬上就會執(zhí)行拿timeline的動作织阳,
  兩個動作并行執(zhí)行,假如各需要1S砰粹,那么總的時間也就是1S
  它們的I/O操作執(zhí)行完成后唧躲,發(fā)射一個事件,profile和timeline伸眶,
  事件代理接收后繼續(xù)往下執(zhí)行后面的邏輯惊窖,這就是NodeJS非阻塞I/O的特點
  總結(jié)一下:
  Java刽宪、PHP也有辦法實現(xiàn)并行請求(子線程)厘贼,但NodeJS通過回調(diào)函數(shù)(Callback)和異步機(jī)制會做得很自然
三. NodeJS的優(yōu)缺點
  優(yōu)點:
  1. 高并發(fā)(最重要的優(yōu)點)
  2. 適合I/O密集型應(yīng)用
  缺點:
  1. 不適合CPU密集型應(yīng)用;CPU密集型應(yīng)用給Node帶來的挑戰(zhàn)主要是:由于JavaScript單線程的原因圣拄,如果有長時間運(yùn)行的計算(比如大循環(huán))嘴秸,將會導(dǎo)致CPU時間片不能釋放,使得后續(xù)I/O無法發(fā)起庇谆;
    解決方案:分解大型運(yùn)算任務(wù)為多個小任務(wù)岳掐,使得運(yùn)算能夠適時釋放,不阻塞I/O調(diào)用的發(fā)起饭耳;
  2. 只支持單核CPU串述,不能充分利用CPU
  3. 可靠性低,一旦代碼某個環(huán)節(jié)崩潰寞肖,整個系統(tǒng)都崩潰
    原因:單進(jìn)程纲酗,單線程
    解決方案:(1)Nnigx反向代理,負(fù)載均衡新蟆,開多個進(jìn)程觅赊,綁定多個端口;
        ∏淼尽(2)開多個進(jìn)程監(jiān)聽同一個端口吮螺,使用cluster模塊;
  4. 開源組件庫質(zhì)量參差不齊帕翻,更新快鸠补,向下不兼容
  5. Debug不方便,錯誤沒有stack trace
四. 適合NodeJS的場景
  1. WESTful API
  這是NodeJS最理想的應(yīng)用場景嘀掸,可以處理數(shù)萬條連接紫岩,本身沒有太多的邏輯,只需要請求API横殴,組織數(shù)據(jù)進(jìn)行返回即可被因。
  它本質(zhì)上只是從某個數(shù)據(jù)庫中查找一些值并將它們組成一個響應(yīng)卿拴。
  由于響應(yīng)是少量文本,入站請求也是少量的文本梨与,因此流量不高堕花,一臺機(jī)器甚至也可以處理最繁忙的公司的API需求。
  2. 統(tǒng)一Web應(yīng)用的UI層
  目前MVC的架構(gòu)粥鞋,在某種意義上來說缘挽,Web開發(fā)有兩個UI層,一個是在瀏覽器里面我們最終看到的呻粹,另一個在server端壕曼,負(fù)責(zé)生成和拼接頁面。
  
  不討論這種架構(gòu)是好是壞等浊,但是有另外一種實踐腮郊,面向服務(wù)的架構(gòu),更好的做前后端的依賴分離筹燕。
  如果所有的關(guān)鍵業(yè)務(wù)邏輯都封裝成REST調(diào)用轧飞,就意味著在上層只需要考慮如何用這些REST接口構(gòu)建具體的應(yīng)用。
  那些后端程序員們根本不操心具體數(shù)據(jù)是如何從一個頁面?zhèn)鬟f到另一個頁面的撒踪,他們也不用管用戶數(shù)據(jù)更新是通過Ajax異步獲取的還是通過刷新頁面
  
  3. 大量Ajax請求的應(yīng)用
  例如個性化應(yīng)用过咬,每個用戶看到的頁面都不一樣,緩存失效制妄,需要在頁面加載的時候發(fā)起Ajax請求掸绞,
  NodeJS能響應(yīng)大量的并發(fā)請求
  總而言之,NodeJS適合運(yùn)用在高并發(fā)耕捞、I/O密集衔掸、少量業(yè)務(wù)邏輯的場景
五. 結(jié)尾
  其實NodeJS能實現(xiàn)幾乎一切的應(yīng)用
  我們考慮的點只是適不適合用它來做

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市砸脊,隨后出現(xiàn)的幾起案子具篇,更是在濱河造成了極大的恐慌,老刑警劉巖凌埂,帶你破解...
    沈念sama閱讀 218,525評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件驱显,死亡現(xiàn)場離奇詭異,居然都是意外死亡瞳抓,警方通過查閱死者的電腦和手機(jī)埃疫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來孩哑,“玉大人栓霜,你說我怎么就攤上這事『嵫眩” “怎么了胳蛮?”我有些...
    開封第一講書人閱讀 164,862評論 0 354
  • 文/不壞的土叔 我叫張陵销凑,是天一觀的道長。 經(jīng)常有香客問我仅炊,道長斗幼,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,728評論 1 294
  • 正文 為了忘掉前任抚垄,我火速辦了婚禮蜕窿,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘呆馁。我一直安慰自己桐经,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,743評論 6 392
  • 文/花漫 我一把揭開白布浙滤。 她就那樣靜靜地躺著阴挣,像睡著了一般。 火紅的嫁衣襯著肌膚如雪瓷叫。 梳的紋絲不亂的頭發(fā)上屯吊,一...
    開封第一講書人閱讀 51,590評論 1 305
  • 那天送巡,我揣著相機(jī)與錄音摹菠,去河邊找鬼。 笑死骗爆,一個胖子當(dāng)著我的面吹牛次氨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播摘投,決...
    沈念sama閱讀 40,330評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼煮寡,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了犀呼?” 一聲冷哼從身側(cè)響起幸撕,我...
    開封第一講書人閱讀 39,244評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎外臂,沒想到半個月后坐儿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,693評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡宋光,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,885評論 3 336
  • 正文 我和宋清朗相戀三年貌矿,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片罪佳。...
    茶點故事閱讀 40,001評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡逛漫,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出赘艳,到底是詐尸還是另有隱情酌毡,我是刑警寧澤克握,帶...
    沈念sama閱讀 35,723評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站枷踏,受9級特大地震影響玛荞,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜呕寝,卻給世界環(huán)境...
    茶點故事閱讀 41,343評論 3 330
  • 文/蒙蒙 一勋眯、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧下梢,春花似錦客蹋、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至岗屏,卻和暖如春辆琅,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背这刷。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評論 1 270
  • 我被黑心中介騙來泰國打工婉烟, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人暇屋。 一個月前我還...
    沈念sama閱讀 48,191評論 3 370
  • 正文 我出身青樓似袁,卻偏偏與公主長得像,于是被迫代替她去往敵國和親咐刨。 傳聞我的和親對象是個殘疾皇子昙衅,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,955評論 2 355

推薦閱讀更多精彩內(nèi)容

  • [NodeJS] 優(yōu)缺點及適用場景討論 概述: NodeJS宣稱其目標(biāo)是“旨在提供一種簡單的構(gòu)建可伸縮網(wǎng)絡(luò)程序的方...
    笑極閱讀 9,232評論 1 23
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,144評論 25 707
  • 首先紀(jì)念一下第一次被拒6妗!A琛L湎亍!GL犯帷!B笙颉N谅恪!K薪摺;案妗<娌! 被拒的原因是: 說我工程中的actionColor這個方法是...
    No_00閱讀 7,104評論 21 18
  • 今天的認(rèn)知訓(xùn)練是怎樣科學(xué)地遇到貴人 觀察一下我們身邊的一部分人可能你會發(fā)現(xiàn)沙郭,總有些人總是能得到一些人的親睞佛呻,得到他...
    Jimuboy閱讀 285評論 0 0
  • 我又一次走在去教學(xué)樓的必經(jīng)之路〔∠撸可以說路邊的兩棵樹是我看著長大的吓著。亦或是它們看著我成長。是不是看著我每天匆匆去上課...
    yangmei1136閱讀 366評論 0 0