原文鏈接:www.tandemseven.com/b...
如果你打開瀏覽器,搜索“Java與Node.js哪個更快”,你會發現大部分答案聲稱Node.js更快,也有一些人持相反意見。Java使用JIT編譯器,其性能甚至可以超過C++。在這種情況下,爲什麼這麼多人還是聲稱Node.js要比Java快呢?小編現在就跟大家一起往下看。
實際檢驗結果
實際上,在處理原始計算任務方面,Node.js並不比Java快;一旦涉及到IO型任務,Java就沒有競爭力了。也就是說,在典型的Web應用程序執行的任務類型場景中,Node.js運行速度確實比Java更快,在接下來模擬的4種場景測試的結果充分驗證了這一點。
性能因素
爲了更好的理解Node.js如何完勝Java,需要考慮到3個性能因素:IO,併發和計算。這三大因素對於提高應用程序的整體運行速度和吞吐量都是有影響的。
1、IO
根據servlet規範,Java在早幾年前引入的NIO實際上是Java編寫後端服務器代碼的標準。在整個規範中,servlet API都假定代碼可以並且將在每個級別阻塞。雖然過去幾年規範有所改進,能夠允許非阻塞請求處理,但servlet規範的基本範例仍然完全包含IO阻塞。這意味着以非阻塞方式寫入磁盤或使用JDBC寫入數據庫的操作會阻止處理線程執行任何其他操作。雖然Java能夠以非阻塞的方式工作,但是對於基於servlet技術的Java應用程序來說,實現一個非阻塞服務器仍然是不切實際的。對於Java社區來說,這一點是非常遺憾。
另一方面,JavaScript完全支持非阻塞IO。JavaScript API不提供阻塞選項,在每個級別上強制支持非阻塞API規範。這意味着在執行IO操作時,Node將永遠不會被阻塞,並且在等待IO時,Node將始終可以自由地處理其他工作。從而,Node能夠非常高效地使用服務器的處理和內存資源。具體來說,Node只需一個線程就可以同時處理和發出數千個IO操作。
2、併發
在Web框架中,Java和Node以兩種截然不同的方式實現併發。
Java:它爲處理的每個傳入請求指定一個線程。隨着併發請求數的增加,線程數也必須增加。如果計劃同時處理最多100個請求,則需要有100個線程池可供處理。
Node:使用一個線程來處理所有傳入的請求。由於Node是非阻塞的,它有足夠的時間對所有請求執行所有計算和轉換,同時等待任何IO操作。
3、計算
雖然谷歌的V8 JavaScript引擎將JavaScript編譯成機器代碼,這結果讓人印象深刻。但是,在某些場景中,Java是優於Node的。比如,您要讓Java與Node進行純計算PK,計算前5000個素數,那麼Java每次都會輕鬆獲勝。
Java與Node.js性能PK
Web應用程序執行大量的IO。首先,從瀏覽器接受請求;這是IO操作。其次,應用程序通常從數據庫中獲取請求的數據;這也是IO操作。一旦計算出所有響應數據,應用程序就會將響應數據發送回瀏覽器;這也是IO操作。應用程序可能一直都在維護日誌;這還是IO操作。實際上,Web應用程序大部分時間都花在IO操作上,而不是計算。
對於Web應用程序而言,它爲每個請求提供服務,需要執行大量的IO,對比之下,Node要比Java更加的適合。
Web應用程序需要高併發
通常,一個Web應用程序有很多個用戶同時訪問。基於Java必須爲每個請求的生命週期指定一個線程,所以它需要大量線程來實現併發。如果在同一時間,應用程序的訪問用戶增加,那麼在所有這些線程之間進行時間分割,很快就會變得非常昂貴並且低效。最終,隨着線程數量的增加,操作系統忙着在所有線程之間進行切換,將變得非常繁忙,以至於CPU時間爆滿後無法做任何實際工作。
這種大規模的情況下,Node的效率就很明顯了。當Node以最大負載運行時,雖然CPU會非常繁忙,但操作系統能夠輕鬆自如的應付。所有的CPU時間都將用於服務請求上。
Java與Node性能PK模擬
爲了證明Node確實可以超越Java,本文介紹了4種場景,在這些場景中通過使用模擬器來測試這兩種技術的性能。此模擬器的代碼,大家可以通過下面的鏈接找到:
註釋:
本測試中,爲Java實現模擬阻塞IO。有些人可能會認爲使用阻塞IO並不公平地比較Java的性能,但在本測試中使用阻塞IO的原因如下:①Java的JDBC規範仍然是一個阻塞規範,這意味,每當有人使用標準JDBC驅動程序連接到關係數據庫時,都必須阻塞。② Apache Tomcat 8.5在2016年6月才完成了第一個非阻塞Servlet規範,這意味着絕大多數生產Java應用程序在執行IO時仍會阻塞。因此,由目前大多數組織以阻塞的方式使用Java,所以在本次模擬中,阻塞也是最具有代表性的Java。
Java與Node.js性能PK
在第一個場景中,選擇一個純計算工作負載來證明Java的計算優勢。分別在有和沒有併發的情況下進行測試模擬,工作負載情況:
1a:①無併發;②計算500個質數;③執行0個阻塞IO調用。
1b:①有併發;②計算500個質數;③執行0個阻塞IO調用。
測試結果如下:
1a:純計算任務在沒有使用併發時,Java速度是Node的2.1倍左右;
1b:一旦將併發加入到任務中,Java領先Node的速度降低到1.8倍。
場景2:大量IO操作
第二種模擬中,不做任何計算工作,只執行IO任務。分別在有和沒有併發的情況下進行測試模擬,工作負載情況如下:
2a:①無併發;②計算0個質數;③執行4個阻塞IO調用;④處理一個5MB文件。
2b:①有併發;②計算0個質數;③執行4個阻塞IO調用;④處理一個5MB文件。
結果如下:
2a:沒有併發時,Node的速度是Java的3.4倍;
2b:有併發時,Node的速度增加到Java的8.5倍。添加併發後,Node與Java之間的差異更加明顯。
場景3:均衡的工作負載
此場景與典型Web應用程序的請求工作負載最接近,模擬中同時執行IO和計算任務,均衡工作負載。同樣,也是在有和沒有併發的情況下分別模擬。
工作負載情況:
3a:①無併發;②計算500個質數;③執行4個阻塞IO調用;④處理一個5MB文件。
3b:①有併發;②計算500個質數;③執行4個阻塞IO調用;④處理一個5MB文件。
測試結果:
3a:沒有併發時,Node的速度是Java的1.8倍;
3b:有併發時,Node的速度增加到Java的4.9倍。
場景4:長時間運行的查詢
工作負載情況:
①計算500個質數;②發出一個很長的阻塞IO調用——10s響應時間;③處理一個5MB文件
測試結果:
Java每秒6個請求;Node每秒64個請求,是Java的10倍
觀察結果能夠發現,執行長時間運行的查詢,Java運行的性能大大受影響,但相同場景下,Node的性能幾乎沒有降低。也就是說,Node完勝Java。
結論
在典型Web應用程序的真實場景中,Node確實是比Java運行速度更快、更具可伸縮性。對於Web應用程序開發來說,Node的性能是難以比擬的。由於Web應用程序大部分時間都在做IO,並且需要高併發,相比之下,Node顯然是最終的贏家。
關於Node.js的性能指標
1、事件循環
事件循環意味着能夠在隊列中執行代碼。事件循環能讓Node.js執行非阻塞IO操作。因此,服務器可以處理無限數量的操作。系統可以處理異步操作。事件循環這個指標衡量事件處理延遲。
2、實時用戶行爲
實時用戶行爲指的就是用戶(客戶)在使用應用程序時所做的事情。舉個例子,Uber或Netflix用戶可在幾秒鐘內完成業務交易,這就反映出了了Node.js的效率。實時用戶行爲這個指標是測量響應時間的。
3、外部框架
Node.js應用程序也同樣依賴於其他的服務、系統和數據庫。它可能會連接到其他應用程序,緩存等,因此也必須記住這戲依賴關係。通過這些外部框架,可以檢查應用程序的響應時間,請求率,錯誤率,內容大小,API,等等。
4、進程內存
Node.js有一個很棒的助手工具——垃圾收集器,它管理應用程序的內存並防止內存泄漏。首先,您可以測量在GC上花費的時間——運行越多次,系統中的暫停次數也就越多。其次,還可以比較每次運行時的內存並檢查構建趨勢。
Node.js的優點
Node.js是一種非阻塞事件驅動模型,它能夠讓開發人員實時構建應用程序。通過推送技術和雙向連接,許多大企業都在使用它。那麼,使用Node.js都有哪些好處呢?
小編跟大家一起來看下:
1.速度(在Google JS引擎上運行);
2.非阻塞I/O模式
3.數據流(HTTP請求和響應作爲的單個事件)
4.實時應用(客戶端和服務器端)
5.統一的數據庫查詢(JSON格式)
6.編碼簡單快速
7.開源NPM存儲庫(超過600000個模塊)
8.代理服務器能力
9.快速的開發週期
10.服務器上的業務邏輯
11.適用於Android設備