導(dǎo)讀:本文是從《Node on nails!》這篇文章翻譯而來。文章內(nèi)容如下:
在開始敘述這篇文章之前,我要非常清楚和明確的聲明:“我并不是在鼓勵你放棄NodeJS或轉(zhuǎn)向Java”。
我一直參與在這種爭論中。在我的編程界的朋友中一直存在著一種誤解,他們認(rèn)為NodeJS語言是將來的趨勢。我對Javascript是百分百的喜愛(不是自吹,我有一段時間曾被認(rèn)為是Javascript專家,我寫了很多喜歡js的文章);關(guān)于Javascript閉包的優(yōu)美,原型模式編程風(fēng)格的優(yōu)勢,我是毫無質(zhì)疑。但是,如果把Javascript放到后臺,這就完全是另外一種情況了。
每當(dāng)我看到有人用一些重要的技術(shù)指標(biāo)對NodeJS進(jìn)行測評并宣稱NodeJS是世界上最快的語言時,我都會覺得好笑。(你只要用谷歌搜一下NodeJS vs *你能想到的任何東西*,你就會找到像這樣,這樣,和這樣的東西。)
撇開我的質(zhì)疑,NodeJS的語言模式還是值得關(guān)注的,但我會在我的產(chǎn)品中使用它嗎?我的問題就在這。我在使用NodeJS的過程中發(fā)現(xiàn)了一些非常嚴(yán)重的問題;給人的感覺相當(dāng)?shù)脑。我必須寫一個完整的HTTP客戶包來支持Multipart方式傳送(現(xiàn)在這個包就是人們所知的Reston),這樣我才能把文件發(fā)送到Amazon S3服務(wù)和其它一些REST服務(wù)里(當(dāng)時沒有任何支持HTTP Multipart傳送的組件,HTTPS也有問題,它折騰的我異常痛苦),總而言之,我需要向讀者們說下面幾個觀點:
并不是所有的Web應(yīng)用程序都需要大量的連接,你并不是每天都在開發(fā)一個聊天系統(tǒng)或一個comet系統(tǒng)。NodeJS對處理某些事情很有優(yōu)勢,我們可以用到它。如果你是讓我去在一個IRC服務(wù)器上開發(fā)一個基于websocket的聊天系統(tǒng),我會推薦NodeJS;但,如果你是讓我去把郵件從你的帳號中取出然后存到RDBMS或NOSQL數(shù)據(jù)庫中,那我就需要思量了。
技術(shù)架構(gòu)選擇很重要!接受它!運用它!我看到有些人選擇了錯誤的技術(shù)路線(然后就炫耀說使用了NodeJS),然后又發(fā)現(xiàn)了更好的方法來實現(xiàn)他的任務(wù),于是又放棄了NodeJS。
如果談?wù)撈鹗录䴙榛A(chǔ)的代碼實現(xiàn)和其可讀性,我相信幾乎每個人都會同意:回調(diào)式的代碼通常比正常流程形式的代碼更顯得混亂。
靜態(tài)類型的語言比動態(tài)類型的語言更具有優(yōu)勢。如果你不了解編譯器的內(nèi)部工作原理,就不要理會這一條了。
我的經(jīng)驗已足夠用來做一次測評的了。我有一臺常見的中等性能的機器(3G內(nèi)存,雙核處理器),做為對比,我會直接使用Java NIO來處理HTTP請求,以“hello world”做為響應(yīng);同樣的過程用NodeJS實現(xiàn)一次。
NodeJS代碼非常的直接。我使用的版本是Node 0.4.9。請注意,這個操作依賴于’http’模塊,因此又依賴于’net’,’stream’等模塊。這些都是NodeJS的基本功能模塊(我沒有做任何特別的事情),它們依賴V8的JIT來實現(xiàn)高速的運行。
在Java上,我使用Java的NIP和selector通道來實現(xiàn)NodeJS上的相同效果(單線程事件分發(fā))。代碼如預(yù)期中的一樣,有點長,因為要做循環(huán)處理。我盡量把所有的代碼都放到同一個文件里,所以,代碼沒有做模塊化等優(yōu)化。就是這兩個文件:Runner.java和core.SocketSelectorCore.java。我使用了HashMaps,字符串的split,indexOf等方法來實現(xiàn)基本的HTTP頭信息的分析,以此模擬一個普通的請求流程(讀,分析,回應(yīng)循環(huán))。我使用的方法并不是很高效,但一般的時候這些方法都不是問題。
現(xiàn)在使用“node test.js”來啟動NodeJS,使用Apache Benchmark(ab -c 1000 -n 100000),1000的并發(fā)量[細(xì)節(jié)信息],大概是每秒鐘4-5千個請求的壓力運行三次。
在拿我寫的Java NIO的程序測試之前,我需要提醒大家?guī)讉事情。Java是一個野獸,你有一大堆的選擇參數(shù)來調(diào)控JVM的垃圾堆棧大小。在我的測試中,我使用JVM運行參數(shù)是“java -server -XX:+PrintCompilation -XX:+UseConcMarkSweepGC Runner”。請注意,我使用的是verbose模式的JIT編譯,這樣我就能知道JVM已經(jīng)初始化完畢,可以開始測試了;我還改變了GC的方法(我試了各種方法,但看起來這個方法最好)。當(dāng)JVM完全啟動編譯后,我運行了相同的Apache Benchmarks [細(xì)節(jié)信息]測試,Java能處理每秒鐘8千-8千5百的請求。
我嘗試了不同的JVM堆的大小和一些其它的參數(shù);結(jié)果非常的有趣。在我的機器上,我一直能達(dá)到每秒6千的處理能力。降低并發(fā)量((-c 100),處理能力能達(dá)到11000/s。如果你仔細(xì)看,你會發(fā)現(xiàn),相對于NodeJS,我在請求里封裝了更多的字節(jié),但這并沒有影響Java的處理能力。得到了這些數(shù)據(jù)后,我還使用JRuby,用它那神奇的語法寫了一個很粗糙的代碼。對JRuby上一些參數(shù)的微調(diào),用這個很簡單的程序,我仍然能得到每秒4000-4500請求的處理能力。
現(xiàn)在,剩下的問題就是,我為什么要做這些,這些說明了什么?我想答案是相當(dāng)明白。從個人的角度,我喜歡Javascript和NodeJS,但我不接受人們說的“NodeJS能做X但Y語言做不到“的言論。我認(rèn)為把Java或PHP或其它語言跟NodeJS進(jìn)行比較的行為是愚蠢的。
Java的JIT相當(dāng)?shù)南冗M(jìn),而Google也把V8發(fā)展到了一個新的高度。像Netty NIO和Mina這樣的框架已經(jīng)存在很久了,只是因為Java的古怪的語法,對內(nèi)存的貪婪,以及學(xué)習(xí)曲線,才沒有引起人們的注意。我只是要破除“NodeJS因為它的異步特征能處理更多的連接,能讓你寫回調(diào)風(fēng)格的代碼,也就是能寫出更好的代碼”的謬論。我的答案相當(dāng)?shù)暮唵危骸笆褂肑ava寫核心代碼,用JRuby或Scala的優(yōu)美語法封裝,你會得到一個更好的處理事件驅(qū)動系統(tǒng)的方法”。
文章出自:外刊IT評論
聲明:本網(wǎng)部份文章為轉(zhuǎn)載文章,在每篇文章底部有說明,文章的觀點和立場僅代表作者個人立場,不代表微網(wǎng)立場,若是文章轉(zhuǎn)載中有侵范您的權(quán)益,請發(fā)郵件到 493149@qq.com或致電13922854199通知刪除,謝謝!