Node.js 真的不適合大規模開發嗎?
總是聽說大公司都是用 Java 的,即使用 Node.js 也是用在偏「前端」。這主要是由於哪些方面的問題呢?不支持多線程?難以多人合作?
節選自狼叔新書,關於Node.js後端開發的章節
一般,後端開發指的是 `Web` 應用開發中和視圖渲染無關的部分,但現在架構升級,`Node` 承擔了前後端分離重任之後,有了更多玩法。從帶視圖的傳統 `Web應用` 和 `面向Api介面應用`,到通過 `RPC` 調用封裝對資料庫的操作,到提供前端 `Api` 代理和網關,服務組裝等,統稱為後端開發,不再是以往只有和資料庫打交道的部分才算後端,這樣,就可以讓前端工程師對開發過程可控,更好的進行調優和性能優化。
對Node.js來說,一直沒有在後端取得其合理的佔有率。原因很簡單
- 1)利益分配,已有實現大多是Java或者其他語言,基本是沒法撼動的,重寫的成本是巨大的,另外,如果用Node寫了,那麼那些寫Java的人怎麼辦?搶人飯碗,這是要拚命的。
- 2)Node相對年輕,大家對Node的理解不夠,回調和非同步流程式控制制略麻煩,很多架構師都不願意花時間去學習。儘管在Web應用部分處理起來非常簡單高效,但在遇到問題時並不容易排查定位,對開發者水平要求略高。
- 3)開發者技能單一,很多是從前端轉過來的,對資料庫,架構方面知識欠缺,對系統設計也知之不多,這是很危險的,有種麻桿打狼兩頭害怕的感覺。
- 4)Node在科普、培訓、佈道等方面做的並不好,國外使用的非常多,國內卻很少人知道,不如某些語言做得好。
了不起是個不能隨便說的詞兒,對於 Node.js 來說,簡化並發編程,用了不起來形容並不過分,在2009年橫空出世時,確實是獨一無二的。但在今天,已經8歲的 Node.js 有了更多、更為廣泛的應用場景,它已經遠遠大於當初設計時的初衷了,我覺得用更了不起來形容已經不過分了!
不支持多線程?是因為Node幫你做了,你只專註於業務實現就好了,這點上說Node是非常了不起的,你去寫寫java的多線程就知道有多蛋疼了,node和go其實都在有意削減這塊。
難以多人合作?你估計是想說面向對象編程,es6小兒科的oo確實不咋地,可是還有TypeScript啊,es6超集,外加各種oo特性,幾乎java有的它都有,作者是安德烈,borland傳奇,c#之父,未來前景無限
狼叔一直是堅信Node全棧必將統治大前端!
回復
1)你根本就沒有深入使用ts,那段話會打臉
2)如果業務複雜度一樣,重構go和js差別有那麼大?看熟練程度吧,這話不客觀
3)開發時不看gc,上線不做基準,那說明什麼呢?
Node適合的是io密集的任務,互聯網開發99%都是io密集的任務,所以沒有不合適一說。另外微服務架構下,語言是公平的,有什麼能力用什麼能力,Node後端也必將佔有一席之地。
沒太深入了解過Node服務端開發,但覺得這是同類問題:「PHP不適合大規模業務嗎」?「為什麼XX公司從Python轉Go?Python真的扛不住了嗎」?
一方面現在的大規模業務很多都是幾種技術搭成的技術棧。即使是Java,別以為一個Tomcat + Spring MVC就能扛起「大規模」,拋開硬體不提,同樣需要集群、隊列等各類技術工具的支持,甚至PHP或Node可以應用在應用層作為膠水層或API供應上。而很多的PHP應用,除了Nginx、Apache、MySQL此類技術,Redis、Memcache也往往發揮重要作用。
另一方面,關注業務層面的問題解決才是正解。沒看到許許多多公司初創時往往選擇快速開發的技術棧,業務規模上量了扛不住了,再考慮更新換代技術棧。如果一開始就想著什麼大規模應用,很可能「死了」都未必用得完這麼多「技術能量」唉。所以說一開始就抱著以一門「完美」的編程語言伴隨終身的想法是不切實際的「形而上」念頭。
再舉個例子,像全球最大的移動端圖片社交應用Instagram一直用Python,而且剛從Python 2完全遷移到Python 3。一個擁有超過30億註冊用戶的業務,使用的居然是外界稱為「慢」的Django,這是不是很值得我們深思呢?
所以我覺得,與其動不動思考「XX編程語言到底適不適合大規模應用」,還不如通過多想辦法改造既有技術來挖掘潛力,來得實惠。這也更能體現開發者的「極客精神」。我來說一下,為什麼不適合開發大型項目:
1. 大公司都有自己的技術沉澱,不會輕易選擇使用NodeJs開發,而放棄傳統的Java或.net或Go等。
2. NodeJs的內存佔用。動態類型的語言,GC方面還有問題,一不小心就有GC不到的。並且內存泄漏並不容易發現。GC這一塊,如果你有業務是要開多個定時任務,秒級別的做一些任務,比如,DB查詢&>計算&>修改db數據&>調用RPC&>輸出。然後你會發現內存持續增高,到某個值之後,才GC釋放內存。內存佔用一直介意的地方。你不能指望每一台伺服器都是8星8鑽,不care那些內存。一個大型項目,是有可能多個語言開發的。內存不能都讓佔了
3. 從語言本身,動態一時爽,重構火葬場。重構代碼都是小心翼翼的,改完之後還要跑通testcase。改的過程就相對編譯型語言來說,會花你很多時間。你可能會說: "這不是有Typescript嗎"。它也並不安全。不是每個庫都有聲明文件,也不是每個參數,返回值,你都會定義類型,有可能的時候你都會定義any。Typescript也只能說是增加了一層不嚴格的類型約束。而編譯型語言,參數和返回值都必須定義,一開始可能會花點時間,可是等你再回頭看代碼,或者重構,你就知道他的好了。
打個比方,如果GO寫的庫重構花10分鐘,那麼JavaScript的可能要30分鐘,這就成了效率問題。4. 目前來看,NodeJs更適合做工具型。因為可以快速開發,不用定義/轉換各種類型,對性能不要求高,社區有很好的工具。
5. 代碼可讀性。JavaScript的代碼可讀性真的很差。沒有類型和IDE的跳轉,完全考驗寫庫的人的功底。而複雜的庫,對於使用者來說是不透明的,因為你不知道它內部是如何運作的。有人會說: "不懂不會去看源碼嗎?",大哥,你去看webpack, Babel, pm2這些試試。也許你能看懂,但是絕對花很多時間。我就相比GO來說,很多GO庫是沒有文檔的,為毛?因為代碼即文檔。你要讀懂一個GO庫的源碼,會比讀懂JavaScript庫的源碼容易得多的多的多。
這也體現在多人合作方面,Go有fmt,不用跟我吵使用2個空格還是4個,是用eslint還是prettier,function和{要不要在同一行,fotmat之後,大家都一樣。Go的IDE提示很好,即便你引用的庫帶來了Breaking Change, 你也能很快的改過來。即便你同事寫的庫沒有文檔,你照樣也會用。
這就是維護成本
6. Node的優勢,海量的npm包。但是這些包的質量,參差不齊。而且為什麼這麼多的包,因為Node缺乏核心標準庫,所以才有那麼多人,樂此不疲的造輪子。以及依賴地獄,幾行代碼就能解決的事,偏偏要引用一個庫。
所以最後,個人認為,Node適合做view層和代理,比如react, ng的ssr以及http和socket代理。當然也能做腳本和工具。
真正的後端業務還是得用其他語言實現。更快速,更嚴謹的語言。
目前確實不適合,但主要原因並不是因為性能問題,畢竟負載不夠疊機器,並發不夠加隊列容量。但由於node不像JAVA一樣要寫一大堆聲明和定義。所以自然一群渣渣寫JAVA寫出來還是沒什麼大毛病,至少還能看。但是一群渣渣寫動態語言可以說會寫的十分混亂,畢竟太靈活,設計再好的架構也能被渣渣們顛覆掉,到最後就容易無法管理,以至於不斷重構。當然如果是大神團隊,他們心裡早就有對應的各色聲明和定義。用動態語言不僅能少寫很多裹腳布,還能更快的開發。畢竟定義和聲明都是用來限制別人寫渣,而大神團隊還需要限制這個?但重點!!!node開發者本來就不多,你還要組建大神團隊,這就很難了。node大規模開發怎麼說也要集齊100個大神來召喚神龍吧!:)
大規模開發一定有一個前提條件,就是能讓像我這樣的野雞程序員也能填代碼,並且不會犯錯。從這點上來看,node還需要一個ts
非同步思想,玩不轉,至少也得有經過封裝的同步方法。凡是弱語法的,都容易被認為不適合大型開發,語法提示、代碼維護等因素。
先定義好什麼是大規模開發。是指一起用的人多,還是實現的功能多,還是node開發的服務訪問量多。
如果是人多,大家需要同意的風格,建議直接上TS。它給你靜態語言基本的功能,還支持和JS混搭。
如果是功能多,Node直接上沒有問題,現在NODE 8LTS版本已經支持async和await了,沒有原來那麼麻煩。
如果是訪問量大,那NODE肯定沒有問題。尤其是API網管這種。
希望可以幫助到你
技術積累問題,和語言關係不大。
對任何一個大型電商後台來說,幾年之後維護和迭代需要大量人力,語言開發效率高低毫無影響。
而開發效率對新網站、新創意來說又是最重要的。
不能拋開場景討論。比如CPU密集型場景確實不適合。
即使公司願意採用node去做後台,但目前也最好只用於偏前端模版和路由處理的部分,和數據打交道的最好交給別人,除非團隊願意花時間磨合或者有很多高手在。另外,單純從技術角度看,都適合用node,我就一直用。
應對大規模需求是需要整套的解決方案的。。
前段時間隔壁組在測模板渲染性能,結果是JAVA勝出。但是最後還是選擇了node,為什麼呢?因為node開發成本更低。非同步是node的優勢所在,固然JAVA也可以寫promise卻會繁瑣不少。從開發成本上考慮而選擇了node(更別提老闆的deadline了)。
剛剛工作的時候我用的ssh,用過的人肯定知道這東西有多啰嗦。在play出來後嘗試部分項目使用,開發速率大幅提升。之後所有項目都轉到了play上。
而後node出現了,出於對js性能擔憂一直都沒有上過生產。另外,非同步回調很容易產生回調地獄。相比io上的優勢,更傾向於JAVA那種多線程異常捕獲,覺得更為可控。
然而對於node轉變是始於promise的出現,這將回調變得更加易於控制。看起來似乎沒有副作用了?就開始嘗試node項目。實際使用上,覺得node更適合web開發(其他語言入Python、Ruby沒試過,所以可能說的有誤差)。到後來async出現,寫了你就回不去了~
所以我建議如果沒有兩個都嘗試過,可以嘗試寫寫。自己比較比較。大部分項目都沒有到對性能錙銖必較的地步。
當然了,還是看團隊技術棧。老闆僱人是為了幹活。
推薦閱讀:
※Node.js 發展前景如何?適用於哪些場景?
※nodejs 應該學習哪些框架?
※什麼是 GraphQL?
※Node.js+Node-webkit的開發模式前景如何?