標籤:

如何理解 Ryan Dahl 最近專訪中的言論「Node 也許不是構建大型服務的最佳選擇」?

英文原文:https://www.mappingthejourney.com/single-post/2017/08/31/episode-8-interview-with-ryan-dahl-creator-of-nodejs/

譯文:http://mp.weixin.qq.com/s/GjJHWv84kkEINZny00D_4Q


引自: Mapping The Journey 訪談時到底說了啥?

https://www.mappingthejourney.com/single-post/2017/08/31/episode-8-interview-with-ryan-dahl-creator-of-nodejs/ 這訪談都出了一周了,這兩天忽然吵得厲害,Ryan Dahl 到底說啥了?

Ryan Dahl 是 Node.js 的創造者,他目前在 Google Brain 工作。在這個訪談里,他回顧了自己 6 歲從 Apple IIc 開始學編程,中途放棄了代數拓撲學的博士跑去南美玩耍,機緣巧合搞起了 Ruby on Rails 的 Web 開發,玩過 Rack 和 Nginx 後,2008 年底 Chrome 發行時看 V8 的源碼發現 JavaScript 是單線程完全非阻塞(nonblocking)的,正好手頭也沒事兒,就花了幾個月時間把 Node.js 搞出來了。

然後他解釋了 2012 年左右,一方面 Node.js 里能做的東西都做差不多了,接下來就剩改不完的 bug 了;另一方面當初堅信非阻塞這一套是終極解決方案,後來發現並沒那麼終極,特別是 2012 年看到 Go 的 Green Thread 實現得不錯,對程序員是「同步」風格編程介面,訪問系統I/O卻是完全非阻塞的,Node.js 成為伺服器端終極解決方案的可能性不大;以及,成為萬眾焦點,不能隨便發表意見亂說話很不爽;於是就退出 Node.js 項目了。

最後說了因為強大的數學和編程背景而得以加入 Google Brain Residence Program 主要從事圖像轉換生成方面的工作。

中間有兩處讓 Node.js 用戶比較受傷的言論:

That said, I think Node is not the best system to build a massive server web. I would definitely use Go for that. And honestly, that』s basically the reason why I left Node. It was the realization that: oh, actually, this is not the best server side system ever.

for a certain class of application, which is like, if you』re building a server, I can』t imagine using anything other than Go. … … I think Node is not the best system to build a massive server web. I would definitely use Go for that. And honestly, that』s basically the reason why I left Node. It was the realization that: oh, actually, this is not the best server side system ever.

很顯然,人現在是 Golang 粉,對於有這麼強 C/C++ 能力的人來說,更喜歡 Go 其實也挺好理解的吧。對於 Go 擁躉確實可以得意一下,連 Node.js 他爹都說 Go 更好;至於 Java 啥的就別瞎摻和了,Java 可是早早的把 Green Thread 幹掉只留 Native Thread 的哦。

超大規模伺服器端開發從來不是簡單的事情,goroutine 在語言層面提供了 go 關鍵字可以把普通函數做為 coroutine 來調度,並為 goroutine 之間通信準備好了 channel 這種抽像,上手是比較省心的,實際使用還是需要深入理解並行和同步的本質。

而 Node.js 其實也沒差得哪裡,ES2017 加上 async/await 之後,語法層面的回調負擔已經消除得差不多了:

Go

func calc(){}
func main(){
go calc();
}

JS

async function calc(){}
async function main(){
await calc();
}

是不是看著挺像?

coroutine 目前 Node.js 上還沒有標準實現,自帶的只有基於進程的 Cluster 機制,而對於多數操作系統,子進程的創建和切換開銷還是很可觀的。不過 Node.js 有 native add-on 呀,像 https://github.com/audreyt/node-webworker-threads 這種東東已經不少了,另外想試試 fiber 也可以 https://www.npmjs.com/package/fibers 。實在是覺得 goroutine 好,https://www.npmjs.com/package/cochan 也可以搞嘛。

一句話,不管是 TJ 還是 Ryan,技術人員大多喜新厭舊的,不管他們今後是站還是撕,也只是一家之言罷了,他們的離開無疑是 Node.js 社區巨大的損失,但是 Node.js 的發展早已不繫於他們某一人,而在你我這些仍然喜歡著的人們。


原來你們以前不是這麼想的??


看你自己咯?如果Node是你所需,就算如Dahl所說也不影響你;如果確實不適合也很正常,天下哪有什麼銀彈?Java是銀彈?C艹是銀彈?天下只有口水。

Dahl只是再次詮釋了「沒有銀彈」這一基本道理而已。

對了,Dahl還在這篇訪談中讚譽了Ruby,我想問一下「如果看待Ryan Dahl讚美Ruby?」。有Rubyist沒?走起。


Ryan Dahl 的話沒有參考價值,一個逃兵沒有權利評價 node。


其實問題的重點是「大型服務」,什麼是大型服務,我想國內也就只有類似於BATJ之類的公司才有可能遇到大型服務。可是在微服務大行其道的今天,我們還會再機會做出一個大型服務來嗎? 對於他所言的大型服務,也許他們谷歌有,但是我們見不到。

Node.js的初衷就是用來處理 I/O 的,計算密集型目前是它的硬傷(也許以後會解決?反正我不知道)。而我們平常所做的 Web 應用,也就是增刪改差的變種,用 Node 足以。但是Ryan Dahl現在處理機器學習的工作,Node是完全指望不上了,它不適合做運算。如果Ryan Dahl說的大型服務是這種,那我就得承認了,Node 不行。

其實, Node是支持C++ Addon 來解決計算密集問題的,但是C++的開發者認為,寫這玩意兒沒有必要,我用C++就能解決一切問題,而Node開發者卻認為C++太難,自己根本就寫不出。這下子就尷尬了。


這兩天被這個刷屏了。

我只好說一個,你們啊,too simple,sometimes naive。

這個世界上有多少項目能夠得上『大型服務』?

1%?我看都說高了。

而且,Ryan Dahl 講這個話,言外之意不就是:

除了構建『大型服務』這個 niche market 之外,

Node 就是好就是好;

Go 就是渣就是渣。

當然如果你去問他,他肯定是不承認的。

所以說你們啊,還是要提高自己的知識水平!懂我的意思——識得唔識得啊?

【註:這個答案之前隨手寫的,可能有些人誤解了我的意思。我這個答案當然有戲謔的成分。我也不反對討論語言的優劣,但得明白某人講某話的語境。所以我用了一種把話說到極端的方式來提示這一點。不過很多時候還是得把話說得更直白,所以現在做個補充。對於 Ryan Dahl 來說,他最初的動機只是想做一個事件驅動的高性能伺服器方案,恰好JS最適合(為什麼適合這個問題里就不解釋了),然後做了4年他的核心idea已經實現了,剩下都是相對無聊的瑣事(社區驅動已經讓他做了很多他本來並不想做的事情),或者就算是重要的問題,也都已經超出了他本人的掌控範圍了。比如很多地方要再優化完全有賴於V8(而V8本來不是為伺服器端設計的);又比如coroutine之類的問題是語言級別的問題,不是單獨node可以決定的,且從之前他的選擇來看,強行修改出一個方言來不是他會採用的方式。這個時候看到Go語言,這是從設計目標上就克服前述問題的,也沒有其他因素(已有的語言和引擎)的制約,當然會認為這才是最理想的。Go並不是沒有缺點,我相信Ryan不可能不了解,比如被說爛的沒泛型,只不過就『高性能伺服器方案』的目標來說,Go的那些缺點都不太重要。我想雖然node達成的成就他是很驕傲的,但是就其初心來說,看到Go的出現說不定會沮喪。Ryan Dahl牛逼之處也在於此,他可以毅然決定放手,轉向Go(儘管後來他其實搞AI去了),並且在採訪中不怕說Go比node更適合構建大型服務,這說明其作為頂級技術人的純真之心。相比之下,只會揪著一句話反覆標題黨的,怎麼說呢,對媒體來說雖屬正常,對技術人來說卻要警惕。】


就是字面意思啊。

這都理解不了還寫啥代碼。

很多前端沉浸在 JS 的世界無法自拔,當年 TJ 也說了 Go 比 Node 好,現在 Node.js 的作者也說 Go 比 Node 好,你說怎麼理解

我理解的是

TJ: Go 比 Node 好用

Node 之父: Go 比 Node 好用 +1(在 Web 開發方面

你一直坐井觀天,現在兩位大佬告訴你井外面的天不止那麼大,你會不會走出去?

這兩位可是真大佬,身經百戰,他們的話信不信由你了。

只有前端才會首選 Node.js 做 web 伺服器,因為除了 JS 其他一概不會

真正的程序員會對比多種語言框架的優劣,擇優使用。而不像某些前端,只用 JS 方案。

某些前端的選型是這樣的

資料庫一定要 mongodb,因為像 JSON,明明 postgresql 更合適。

配置文件一定要 JSON 格式,因為像 JS。但是 JSON 配置文件很反人類啊。

桌面開發一定要 electron,移動端一定要 React Native,完全不管性能和功能。

build 一定要 grunt gulp,完全不學 bash make。

這就很呵呵。

我沒說 Node 不好,我是說你應該看看別的好東西,別抱著 JS 到死。

去看看 go,看看 Rack,看看 Rails!

ruby 社區給 JS.社區帶來過巨大的影響,接下來會是 go 社區。


Node.js 做一些工具類應用確實方便,這也是JS社區這麼繁榮的原因之一。

但是Node 做大型服務

還是省省吧畢竟大部分JS程序員真的只會寫JS

更別奢求什麼後端開發經驗了

見過太多由只會JS的程序員用Node寫的web服務了,講真,這種系統交接給我不讓我重寫,我立馬辭職

注意,我這裡並不是黑Node.js,相反我覺得Node非常好也是我做一些工具的首選畢竟相關工具鏈熟悉社區繁榮攢東西方便。

我這裡黑的是那些只會JS然後有了Node就以為自己會做後端開發了的大哥們(ㄒoㄒ)

Node 確實不適合構建大型服務,因為畢竟有過構建大型服務的經驗的人都不多,你還在前端圈子裡找...活著不好嗎?

語言從來都不是壁壘,關鍵看誰來用了


現在我用node做線上服務基本上只是為了政治正確,包括但不限於:

  • 使用公司其他部門開發的node web框架,有時候遇到問題可以獲得一些他們的技術支持
  • 公司已經把node的運維棧搞好了,不需要再去求著運維搞什麼,也不用擔心他們甩裸機給你自己運維
  • 選型直接選node就不需要再給其他人解釋為什麼要選別的,撕逼的過程用來開發多好

這就是我經常掛口頭上說技術選型的政治正確的含義

如果不是node,我會用PHP或者C#,呃說真的,因為我只用過PHP和C#。


任何人只要使用Node構建過一次非玩具型服務,就會發現:

  • 就算有Unit Test,還是不敢重構
  • npm install經常有驚喜。npm update 99%有驚喜。package-lock.json不能跨平台,是廢的 (package-lock.json and optional packages · Issue #17722 · npm/npm)
  • 「優美」的Stream API


這大佬在採訪時說話只說了一半,光看文本不知道他在想什麼。

腦補一下他沒說的,大概可能有這麼幾點

1.單線程非同步沒法簡單地調用多核的能力。用開進程的方式太重,開銷太大,而且用起來不方便,得設計個寫法把數據傳給其他進程。Go的green thread就很容易。

2.單線程非同步沒法在執行同步代碼里交出執行權。(除非改成coroutine)

3.同理,一段同步代碼要改成coroutine的話,所有call site都要改動。

反對其他答案對生態工具類型系統的評價。人家大佬應該在講非同步模型的事兒


當年Ryan退出江湖的時候就黑了自己創造的Node.js一把,如今又出來這麼說Node,比起某些只說自己創造的東西好話的人,這點上Ryan是很有勇氣很有個性的,有種!

這裡我也不想去爭辯Node是不是真的適合大型應用,我只想說,一個東西如果創始人都不看好,卻依然發展得很好,那就說明這個東西有了自己的生命,比如node,比如某些組織,這說明這順應了某種天道啊!

了解更多行業新奇角度觀點請關注@程墨Morgan


這問題要結合3年前的問題一起來看:如何看待 TJ 宣布退出 Node.js 開發,轉向 Go? https://www.zhihu.com/question/24373004/answer/27588254?utm_source=com.google.android.apps.docsutm_medium=social

多少人的回答被打臉,還有人跑到我的回答下面來大談前後端用JS可以更好的開發前端。實際上,我見過太多人,寫後端不管是用Java、go、還是JS,對HTTP協議一知半解,你前端用著他寫的API還是憋屈。

這問題根本不需要扯很多,就一個樸素道理:術業有專攻,不同領域都有特定工具。我以為Java se和applet掛掉後,大家已經對一招鮮免疫了,沒想到歷史還在重演。


非同步程序難維護的問題並沒有解決,前端用JS是因為別無選擇,(用戶)事件驅動的程序,本身是非同步的,所以程序員不得不適應。

即使有async/await,非同步程序難維護的問題也不會根本解決,不是語法問題,而是編程範式不符合直覺,相比之下同步阻塞的代碼就是好寫好調試得多。

大後台應用經常數據分布存儲,於不同系統之中,這些數據很多時候是彼此依賴的,因為要組合起來完成業務處理目標,也就是說數據之間存在「同步阻塞」的關係,非同步方式訪問多個系統,卻要達到同步的效果,就是拐了一個大彎做PHP,Python本來就做得很好的事情:從多節點取數據,組織這些數據。這種情況下Node沒有效率優勢,因為單線程,多節點取數據都完成不了並行(雖然語法上一眼看去是如此)。

後台程序不是事件驅動的,雖然可以牽強附會,比如把和資料庫交互的過程看成一個事件流。

但它並不「一定」要是事件流,它就是簡單直白的數據流,各種後檯子系統的根本作用,也就是數據存儲分發,架構面向數據,不捨近求遠,更自然。


曾經用這兩種語言做過項目,現在都不想用了。

NodeJs:

  1. 依賴項太龐大了。用NodeJs做項目,大部分時間都在看各種源代碼。
  2. NodeJs 雖然是動態語言,但卻有比Java還複雜的各種範式和版本的問題。
  3. 難以控制代碼入侵。

Go:

  1. 生態不成熟,很多業務沒有統一的解決方式,依賴項的版本和質量難以控制。
  2. 對於一些流行的數據格式,支持都不夠友善。Go語言的模板引擎,Json,XML ,相較於其他語言,笨。
  3. 簡單粗暴的非同步,很容易變成,很難重構和調試的一坨。

個人覺得,用它們做大型項目的都是賭徒。它們明明都更合適做微服務。


儘管 Node 作者都這麼說了。

依然覺得統一前後端技術棧很有意義。

我現在用 Typescript 進行前後端開發,使用 NodeJS 的同時在關注 fibjs 的發展。


分頁阅读: 1 2 3