- 深入淺出Node.js
- 樸靈
- 1869字
- 2020-05-06 16:52:10
1.5 Node的應(yīng)用場景
在進(jìn)行技術(shù)選型之前,需要了解一項(xiàng)新技術(shù)具體適合什么樣的場景,畢竟合適的技術(shù)用在合適的場景可以起到意想不到的效果。關(guān)于Node,探討得較多的主要有I/O密集型和CPU密集型。
1.5.1 I/O密集型
在Node的推廣過程中,無數(shù)次有人問起Node的應(yīng)用場景是什么。如果將所有的腳本語言拿到一處來評判,那么從單線程的角度來說,Node處理I/O的能力是值得豎起拇指稱贊的。通常,說Node擅長I/O密集型的應(yīng)用場景基本上是沒人反對的。Node面向網(wǎng)絡(luò)且擅長并行I/O,能夠有效地組織起更多的硬件資源,從而提供更多好的服務(wù)。
I/O密集的優(yōu)勢主要在于Node利用事件循環(huán)的處理能力,而不是啟動每一個線程為每一個請求服務(wù),資源占用極少。
1.5.2 是否不擅長CPU密集型業(yè)務(wù)
換一個角度,在CPU密集的應(yīng)用場景中,Node是否能勝任呢?實(shí)際上,V8的執(zhí)行效率是十分高的。單以執(zhí)行效率來做評判,V8的執(zhí)行效率是毋庸置疑的。
我們將相同的斐波那契數(shù)列計(jì)算(F0=0, F1=1, Fn=F(n-1)+F(n-2)(n≥2))分別用各種腳本語言寫了算法實(shí)現(xiàn),并進(jìn)行了n = 40的計(jì)算,以比較性能。這個測試主要偏重CPU棧操作,表1-1是其中一次運(yùn)算耗時的排行。在這些腳本語言中(其中C和Go語言是靜態(tài)語言,用于參考), Node是足夠高效的,它優(yōu)秀的運(yùn)算能力主要來自V8的深度性能優(yōu)化。
表1-1 計(jì)算斐波那契數(shù)列的耗時排行

這樣的測試結(jié)果盡管不能完全反映出各個語言的性能優(yōu)劣,但已經(jīng)可以表明Node在性能上不俗的表現(xiàn)。從另一個角度來說,這可以表明CPU密集型應(yīng)用其實(shí)并不可怕。CPU密集型應(yīng)用給Node帶來的挑戰(zhàn)主要是:由于JavaScript單線程的原因,如果有長時間運(yùn)行的計(jì)算(比如大循環(huán)),將會導(dǎo)致CPU時間片不能釋放,使得后續(xù)I/O無法發(fā)起。但是適當(dāng)調(diào)整和分解大型運(yùn)算任務(wù)為多個小任務(wù),使得運(yùn)算能夠適時釋放,不阻塞I/O調(diào)用的發(fā)起,這樣既可同時享受到并行異步I/O的好處,又能充分利用CPU。
關(guān)于CPU密集型應(yīng)用,Node的異步I/O已經(jīng)解決了在單線程上CPU與I/O之間阻塞無法重疊利用的問題,I/O阻塞造成的性能浪費(fèi)遠(yuǎn)比CPU的影響小。對于長時間運(yùn)行的計(jì)算,如果它的耗時超過普通阻塞I/O的耗時,那么應(yīng)用場景就需要重新評估,因?yàn)檫@類計(jì)算比阻塞I/O還影響效率,甚至說就是一個純計(jì)算的場景,根本沒有I/O。此類應(yīng)用場景或許應(yīng)當(dāng)采用多線程的方式進(jìn)行計(jì)算。Node雖然沒有提供多線程用于計(jì)算支持,但是還是有以下兩個方式來充分利用CPU。
? Node可以通過編寫C/C++擴(kuò)展的方式更高效地利用CPU,將一些V8不能做到性能極致的地方通過C/C++來實(shí)現(xiàn)。由上面的測試結(jié)果可以看到,通過C/C++擴(kuò)展的方式實(shí)現(xiàn)斐波那契數(shù)列計(jì)算,速度比Java還快。
? 如果單線程的Node不能滿足需求,甚至用了C/C++擴(kuò)展后還覺得不夠,那么通過子進(jìn)程的方式,將一部分Node進(jìn)程當(dāng)做常駐服務(wù)進(jìn)程用于計(jì)算,然后利用進(jìn)程間的消息來傳遞結(jié)果,將計(jì)算與I/O分離,這樣還能充分利用多CPU。
CPU密集不可怕,如何合理調(diào)度是訣竅。
1.5.3 與遺留系統(tǒng)和平共處
有人會說:“JavaScript一統(tǒng)前后端了,將來會不會干掉其他的語言?”言語中充滿了危機(jī)感。
在Web端,過去大多都是同步的方式編寫的程序,這種串行調(diào)用下層應(yīng)用數(shù)據(jù)的過程中充斥著串行的等待時間,如果采用多線程來解決這種串行等待,又或多或少地顯得小題大作。在Node中,語言層面即可天然并行的特性在這種場景中顯得十分有效。對于已有的穩(wěn)定系統(tǒng),并非意味著我們要拋棄掉。
LinkedIn在他們的移動版網(wǎng)站上的實(shí)踐非常典型地說明了這個問題。舊有的系統(tǒng)具有非常穩(wěn)定的數(shù)據(jù)輸出,持續(xù)為傳統(tǒng)網(wǎng)站服務(wù),同時為移動版提供數(shù)據(jù)源,Node將該數(shù)據(jù)源當(dāng)做數(shù)據(jù)接口,發(fā)揮異步并行的優(yōu)勢,而不用關(guān)心它背后是用什么語言實(shí)現(xiàn)的。
這方面,國內(nèi)的雪球財(cái)經(jīng)也有很好的實(shí)踐。雪球財(cái)經(jīng)是從舊有的Java項(xiàng)目中分離出一個子項(xiàng)目,在這個子項(xiàng)目中,沒有繼續(xù)采用Java/JSP而是采用Node來完成Web端的開發(fā),使得前端工程師在HTTP協(xié)議棧的兩端能夠高效靈活地開發(fā),避免了Java煩瑣的表達(dá);另一方面,又利用Java作為后端接口和中間件,使其具有良好的穩(wěn)定性。兩者互相結(jié)合,取長補(bǔ)短。
1.5.4 分布式應(yīng)用
阿里巴巴的數(shù)據(jù)平臺對Node的分布式應(yīng)用算是一個典型的例子。分布式應(yīng)用意味著對可伸縮性的要求非常高。數(shù)據(jù)平臺通常要在一個數(shù)據(jù)庫集群中去尋找需要的數(shù)據(jù)。阿里巴巴開發(fā)了中間層應(yīng)用NodeFox、ITier,將數(shù)據(jù)庫集群做了劃分和映射,查詢調(diào)用依舊是針對單張表進(jìn)行SQL查詢,中間層分解查詢SQL,并行地去多臺數(shù)據(jù)庫中獲取數(shù)據(jù)并合并。NodeFox能實(shí)現(xiàn)對多臺MySQL數(shù)據(jù)庫的查詢,如同查詢一臺MySQL一樣,而ITier更強(qiáng)大,查詢多個數(shù)據(jù)庫如同查詢單個數(shù)據(jù)庫一樣,這里的多個數(shù)據(jù)庫是指不同的數(shù)據(jù)庫,如MySQL或其他的數(shù)據(jù)庫。
這個案例其實(shí)也是高效利用并行I/O的例子。Node高效利用并行I/O的過程,也是高效使用數(shù)據(jù)庫的過程。對于Node,這個行為只是一次普通的I/O。對于數(shù)據(jù)庫而言,卻是一次復(fù)雜的計(jì)算,所以也是進(jìn)而充分壓榨硬件資源的過程。
- Arch Linux Environment Setup How-to
- 白話區(qū)塊鏈
- Haskell Financial Data Modeling and Predictive Analytics
- 高性能Linux服務(wù)器構(gòu)建實(shí)戰(zhàn):運(yùn)維監(jiān)控、性能調(diào)優(yōu)與集群應(yīng)用
- Alfresco 4 Enterprise Content Management Implementation
- Moodle 3.x Teaching Techniques(Third Edition)
- 注冊表應(yīng)用完全DIY
- 一學(xué)就會:Windows Vista應(yīng)用完全自學(xué)手冊
- Django Project Blueprints
- Red Hat Enterprise Linux 6.4網(wǎng)絡(luò)操作系統(tǒng)詳解
- μC/OS-III內(nèi)核實(shí)現(xiàn)與應(yīng)用開發(fā)實(shí)戰(zhàn)指南:基于STM32
- Web Penetration Testing with Kali Linux(Third Edition)
- 嵌入式微系統(tǒng)
- 微軟360度
- 深入理解Android:卷III