架構選型之Nodejs與Java

前言:javascript

 

身邊愈來愈多的同事談論Nodejs,談其異步IO、事件回調、先後臺統一一門語言,創業的朋友的第一個創業項目也選擇了Nodejs,指望可以使用一種語言節省成本快速完成需求開發。與其餘項目組的同事聊項目選型Java時被他們嘲笑了一把,怎麼這麼不與時俱進怎麼還在用Java。並且發現,愈來愈多的前端同事經過Nodejs輕鬆上手後端功能開發,做爲後端開發工程師倍感壓力。前端

借新項目的機會系統瞭解了下Nodejs的知識體系,本文對了解到的Nodejs技術做了總結,同時將其與Java的相關技術進行了總結對比,爲其餘考慮兩種語言選型的架構師提供選型的決策依據。爲了不爭議,本文避免對選型語言的推薦,也不對將來的發展趨勢作出預測。java

 

語言背景分析:node

 

簡單對兩門語言進行「拼爹」對比,發現有技術深度的事情仍是博士比較擅長,計算機專業的技術又未必是計算機專業的人貢獻:mysql

Nodejslinux

 

Javaandroid

 

Ryan Dahl,非科班出身,數學系讀博士
2006開始學習網站開發,2年後成爲高性能Web服務器專家,3年後建立Node

算法

 

2009年的2月開始開發Node,年末發表關於Node.js的演講

sql

 

2010年由創業公司Joyent贊助開發

數據庫

 

2013年更新緩慢、活躍度下降,糾結於穩定內核及新特性開發

 

2014年8月幾個重要core contributor發起組織(io.js前身),此後高速發展,新功能激進、高速版本迭代、問題反饋快速回復解決,2015年5月Node.js項目和io.js項目都將加入Node.js基金會,io.js繼續發展的同時進行合併,Nodejs的下一個版本將跨1.0直接到2.0

 

詹姆斯·高斯林,卡內基·梅隆大學計算機博士,編寫了多處理器版本的Unix操做系統,是JAVA的創始人。

 


1995年5月23日,Java語言誕生

 

1996年1月,第一個JDK-JDK1.0誕生

 

1997年9月,JavaDeveloperConnection社區成員超過十萬

 

1998年2月,JDK1.1被下載超過2,000,000次

 

2009-04-20甲骨文74億美圓收購Sun。取得Java的版權;

 


2014年3月19日,甲骨文公司發佈Java 8.0的正式版。

 


2000年~今,編程語言排行榜一直在第一第二位

 

 

語言及SDK分析:

Nodejs選擇javascript語法致使了其靈活、面向過程、單進程單線程執行的基本特性。然而得意其語言的靈活性,一些面向對象的特徵也能夠經過邏輯代碼實現,但受阻於ECMAScript的發展速度,總體上Nodejs向企業級應用語法轉型還暫時較慢。Nodejs主打的異步IO事件回調使其更適合服務器的編程,其單進程單線程的特質使得開發變得簡單。得意與社區的活躍語言處於高速發展、SDK不斷地發展穩定豐富。

相比之下,Java是面向對象的具有了面向對象的所有特徵,經歷了20年的發展沉澱愈加的強大、穩健。與Nodejs相比Java是個在各個領域做精做深的技術巨人,然而也正因如此,學習Java的成本要比Nodejs高很大一個臺階,每個小的技術方面都能找到很厚的一本書來。面對異步IO事件回調的新技術Java也在其新的SDK中提供支持與時俱進,相關Java的開源項目也及時跟進。

對比項

 

Nodejs

 

Java

 

函數式編程

 

很是自由,能夠調用、做爲參數、做爲返回值

 

支持高階函數、偏函數用法

 

Java8中支持了Lambda表達式實現函數編程與時俱進

 

類、接口、抽象類

 

原生不支持,自己是面向過程的,可利用函數實現類的定義能力。
ECMAScript 5引入Object.create(),類即對象,主流瀏覽器最新版本支持
ECMAScript 6引入class語法,2015年6月計劃發佈,還需腳本引擎開發支持
無接口、抽象類的概念,能夠利用語言的靈活實現相似接口的特性能力,較爲複雜

 

原生支持,面嚮對象語言基本能力,依賴接口編程下降耦合

 

封裝、繼承、多態

 

原生不支持
利用函數實現相似「類」的封裝,利用prototype實現相似繼承的能力,無多態能力
ECMAScript 6引入繼承語法,2015年6月計劃發佈,還需腳本引擎開發支持
Nodejs中有繼承的概念,但非語言級別的支持
沒有多態的能力

 

原生支持,面嚮對象語言基本能力

 

動態

 

須要重啓或者從新加載

 

依靠jvm的字節碼和內存管理技術,能夠實現動態編譯、動態連接、動態加載、動態變動替換、熱部署

 

異常

 

支持,因爲異步IO事件回調致使異常捕獲較爲複雜。V8不會優化含有try/catch的函數又致使過多捕獲異常產生性能問題。

 

全局捕獲uncaughtException會丟失堆棧一般爲時已晚。

 

Domain機制當前還不穩定。

 

支持,相對更成熟完善些,單線程異常不影響其餘線程。

 

算法與數據結構

 

Node自己提供的較爲簡單,但開源社區相關代碼高速發展中

 

比較穩定完善

 

集合Set\Map\List

 

api能力較弱,ECMAScript 6引入Set和Map,2015年6月計劃發佈,還需腳本引擎開發支持

 

完善豐富的集合容器,支持各類併發場景、業務特殊算法場景

 

事件回調與異步IO

 

語言級別支持,Nodejs殺手鐗能力。

 

監聽器模式實現事件回調,利用事件隊列解決雪崩問題
利用事件機制充分利用異步IO突破單線程編程模型的性能瓶頸
經過異步機制使請求之間無阻塞,達到並行請求的目的,有效的調用下層資源
Linux採用線程池與阻塞I/O模擬出來的異步I/O(libeio)
Windows使用其獨有的內核異步IO方案:IOCP

 

1.4版本開始提供NIO工具包實現同步非阻塞IO
1.7版本NIO2.0提供了異步IO的支持,支持異步IO回調接口

 

進程、線程

 

單線程單進程模式,開發成本低。
高效CPU利用須要部署多個Node.js進程,相對較爲耗費資源,通訊成本較高
單進程帶來的穩定性可靠性問題經過負載均衡、自殺重啓提高

 

支持多線程編程,支持併發控制,較爲複雜,須要有併發開發經驗
相對單進程可靠性更高、更加靈活

 

網絡編程、WEB開發

 

能夠十分方便地搭建網絡服務器
提供多個模塊快速搭建服務端和客戶端,TCP/UDP/HTTP/WebSocket
自己就是個好的WEB開發框架,無須切換語言環境,但也容易形成先後端Js代碼混淆

 

提供的仍是底層API能力,由各個開源項目實現強大而專業的網絡編程框架及WEB開發框架

 

組件模塊、分包分層

 

package.json集合文件夾定義包,包內部可定義多個模塊

 

經過package、類、ClassLoader、壓縮包實現多維度多層次的劃分和複用的能力
OSGI框架實現插件化、熱部署

 

註解、反射、泛型

 

 

原生支持

 

擴展性

 

支持C/C++編寫的邏輯擴展

 

支持C/C++/及其餘可被JVM執行語言編寫的邏輯擴展

 

 

三方開源框架選型:

 

語言選型後面即框架選型,好的框架能夠去除不少沒必要要的重複工做使項目輕鬆獲取強大的功能。固然三方開源框架的引入也帶來的相應的學習成本,一樣的,Nodejs框架因爲發展時間相對較短學習成本相對較低,開發人員更容易瞭解到更多底層的實現源碼,但相對的部分框架容易出現穩定性兼容性問題,加之NPM開發人員水平不一而又沒有很好的審覈機制,選擇一些模塊(尤爲是C/C++模塊)時須要慎重。Java三方開源框架大都已被大量企業大量使用、成熟穩定,提供強大能力的同時做了很好的封裝分層,開發人員付出較高的學習成本後更多的是「傻瓜「式的使用。就WEB開發體系而言,二者均可以找到不少可服用引入的開源框架。

對比項

 

Nodejs

 

Java

 

數據庫

 

針對不一樣數據庫類型引入不一樣的驅動模塊,Mongoose/reids/mysql

 

能夠針對不一樣的數據庫引入不一樣的驅動模塊,也可使用多個開源框架,下降數據庫使用成本、不一樣數據源的遷移成本:
hibernate/ibatis等等

 

MVC框架開發WEB

 

Express/Koa:輕量靈活快速地搭建網站,支持多種模板,利用generatora解決了繁瑣的回調嵌套

 

相關框架均較爲成熟可靠,典型的有:
Structs:發展長達9年,穩定成熟,面對一些新的框架只能做爲稍穩妥的選擇
Srping MVC:爲解決企業應用開發的複雜性而建立,輕量、控制反轉、面向切面
阿里內WebX,其餘的開源框架還有不少
Web容器也多種選擇:tomcat\jetty\jboss等等,隨着java支持nio也持續發展

 

前端模板

 

EJS:強大易用,語法更接近前端語言。Jade語法更接近後端語言,功能更強大

 

Velocity:基於java的模板引擎,阿里主流選擇,內部進行了性能優化,支撐住了淘寶天貓的大流量
其餘:FreeMarker、Jamon、JDynamiTe、Jbyte等

 

Rest開發

 

Restify:Rest應用框架,支持服務器端和客戶端,專一Rest服務

 

JAX-RS:提供了一些標註將一個資源類、一個POJO Java類封裝爲Web資源。
Axis2:Apache項目,同時支持SOAP和REST風格的Web Service。 
Cetia4:基於Servlet API開發,能夠運行於全部的Web容器中

 

Web Socket

 

Socket.IO:跨平臺,多種鏈接方式自動切換,作即時通信方面的開發很方便

 

Netty:異步的、事件驅動的網絡應用程序框架和工具包

 

日誌管理

 

Log4js:簡單易用,winston:功能更強大,稍複雜

 

Log4j:輸出定製、日誌級別格式控制。Slf4j:簡單統一的日誌接口

 

HTTP調用

 

Request:創建各類HTTP請求,支持受權驗證,其實功能仍是很是多的,基本知足絕大部分需求。

 

HttpClient:Apache Jakarta Common 下的子項目,用來提供高效的、最新的、功能豐富的支持 HTTP 協議的客戶端編程工具包

 

異步流程控制

 

Async:使異步流程同步化。Q是另一種很是不錯的選擇,它是實現了promises接口。

 

asyn4j:異步方法調用框架,基於消費者與生產者模式。包括了異步方法執行,異步回調執行,異步工做緩存模塊.支持Spring。

 

定時任務

 

Cron:小巧的定時任務管理模塊。Later功能強大但稍微複雜

 

Quartz:能夠用來建立簡單或爲運行上萬個jobs這樣複雜的程序,讓做業變得易用管理

 

其餘框架

 

社區活躍,更新很是快,但也容易存在不穩定、不兼容的風險。

 

Npm模塊的開發人員水平不一,暫時只能依靠口碑、測試文檔等條件選型

 

各類場景均有不少成熟穩定開源框架可供選擇,公司內部一般也有本身的成熟項目

 

 

產品化分析:

 

就產品化而言,Nodejs雖然在各個方面都有建設,但相對Java還有不少須要繼續完善發展的地方,如系統監控和性能分析領域還不如Java體系那麼完善,受限於單進程單線程模式穩定性部署方面還不如Java那麼靈活,靈活的腳本語言加上Nodejs發展時間相對較短使得系統的安全性還須要經受更多的考驗。同時,先後端代碼均可以使用到js並同時保存在一個開發分支時,單純的依賴目錄去區分先後端代碼,容易形成先後端代碼的混淆,相對不夠清晰。但相信爭議和問題都是暫時的,高速發展的Nodejs會逐步完善完美。

對比項

 

Nodejs

 

Java

 

編碼規範

 

JSLint/JSHint:定義代碼格式規範的規則,統一編碼

 

CheckStyle/FindBug/Code formatter:比較完善,支持持續集成

 

包管理、構建

 

NPM:Nodejs的包管理器,模塊庫發展是十分神速和活躍
Makefile:linux下,依託強大的bash編程
Grunt:依託豐富的插件,NPM加Grunt媲美輕量級的Maven

 

MAVEN:一個項目管理和構建自動化工具,包含了一個項目對象模型、一組標準集合、一個項目生命週期、一個依賴管理系統、插件,方便、擴展性好、功能強大

 

部署

 

腳本方式啓停進程進行部署
forever/pm2:進程容災重啓,Linux上支持的較好,

 

WEB項目利用Maven能夠打包成一個war包,直接部署到容器的指定目錄便可。
依賴部分容器的特性能夠實現熱部署,大部分仍是去除流量後依靠腳本完成重啓。

 

系統監控

 

但針對Nodejs的監控技術仍是比較缺少的,資料也比較缺少

 

JVM提供虛擬機各項指標的監控接口,包括C++和Java的,基於此類接口實現了不少成熟的監控工具,互聯網公司內將不少監控能力WEB化

 

性能分析

 

內存快照分析:node-heapdump/node-memwatch
Chrome:內存快照、CPU Profile

 

基於JVM的工具API實現有多種性能分析工具,能夠分析CPU耗時分佈、CPU調用鏈、CPU熱點、內存分佈、內存熱點、線程阻塞等等。

 

穩定性

 

受限於單進程單線程的設計,穩定性須要引入多進程來解決,限制較大,相對比較耗費資源

 

傳統的多線程、多進程、多機多機房機制,靈活選擇部署,穩定性已經歷過線上的長期考驗

 

安全性

 

腳本語言的安全性較弱加上Nodejs的語法靈活性致使編碼時較容易出現安全問題,已成立Node安全項目有針對性的分析解決Nodejs的安全問題。

 

相對腳本語言安全性較強,漏洞通過多年分析與解決

 

 

執行引擎分析:

 

在瀏覽器方面V8引擎大名鼎鼎讚不絕口,這也是Nodejs選型V8這個最快的Javascript執行引擎的緣由。然而另外一方面,V8引擎專門針對瀏覽器的設計也嚴重限制了Nodejs在服務器領域的大有做爲,彷彿帶着手鍊腳鏈在高速奔跑。因V8引擎的創始人和技術都是來自Java虛擬機,使用了部分Java虛擬機技術適配瀏覽器業務實現,全部相比之下Java虛擬機更加的成熟完善,也必然相對的複雜沉重。

對比項

 

Nodejs

 

Java

 

引擎概述

 

V8:最快的JavaScript虛擬機,參考JVM部分核心技術實現,針對瀏覽器需求場景而專門設計優化

 

JVM:成熟穩定完善的虛擬機技術及體系,各個內部模塊算法等都通過深刻研究造成專業領域,V8的創始人是原SUN的技術人員

 

內存限制

 

V8專爲瀏覽器設計,最大內存佔用:64位1.4GB,32位0.7GB,新生代分佈對應爲最大32M和16M(限制可打開,容易形成延遲,不推薦)
不能靈活的使用內存,必須嚴謹的爲每一份資源做出安排。

 

能夠結合系統的內存狀況能夠按須要設置,而且能夠根據業務對內存的需求靈活設置調優。

 

垃圾回收

 

模仿JVM的分代回收。新生代晉升條件相對固定,複製回收。老生代標記清除回收(壓縮解決碎片問題)

 

廣泛分代回收,有多種垃圾回收算法可供選擇,每一個回收算法有多種參數能夠配置調優,持續發展更新。

 

內存監控分析

 

process.memoryUsage查看內存概況,os模塊的totalmem()和freemem()查詢系統內存使用
--trace_gc打印垃圾回收日誌
內存快照:V8-profiler/node-heapdump/node-memwatch

 

JVM提供C++和Java的接口能夠查詢詳細的JVM內存及系統內存信息
能夠經過啓動參數打印回收日誌,能夠經過jstat命令實時查看
能夠經過jmap或者多種工具dump內存,能夠經過memoryAnalyzer等多種工具分析內存比對內存

 

跨平臺、可移植

 

暫時只能支撐到Chrome瀏覽器支撐得了的平臺

 

任何虛擬機支撐的平臺,更爲普遍穩定

 

擴展性

 

爲瀏覽器設計,擴展性相對較差,體系還不夠完善

 

技術體系比較深,提供多種接口方便三方擴展開發

 

 

其餘一些對比:

 

其餘一些簡單對好比下:

領域

 

對比項

 

Nodejs

 

Java

 

開發工具

 

IDE

 

WebStorm

 

Eclipse

 

測試技術

 

單元測試

 

Mocha/Karma/Jasmine

 

Junit/TestNG/jMock

 

應用場景

 

場景

 

服務器編程,擅長高併發IO密集型程序項目

 

服務器編程、大數據、企業開發、android

 

開發者

 

來源

 

部分是向後臺開發試水的前臺人員,部分是被異步I/O吸引的後臺人員

 

大部分仍是後臺開發人員

 

 

結束:

 

Nodejs的異步IO、事件回調雖是殺手鐗能力,但其餘程序開發語言也都有相應的跟進支持,但Node成功將先後端統一一門語言開發,這絕對是無人能及,吸引了大批的開發者加入。得益但又受限於V8引擎,其發展還帶着包袱,但Nodejs還年輕還處在高速發展中,相信隨着IO.js與Node.js合併、愈來愈多的開發者進行共建,Node會愈來愈穩定成熟。

相比之下Java是編程領域的巨人,20年的發展,愈加的成熟穩定,造成完善的體系完善的生態,Android的流程再次將這門語言推到了巔峯,架構選型永遠是個重點選項。

https://as.h5con.cn/articles/54118?spm=5176.100239.blogcont118673.32.8NFfUv

相關文章
相關標籤/搜索