[譯] Node.js 會永遠只是慢的 Golang 嗎?

掘金翻譯計劃發表於2019-04-30

Node.js 會永遠只是慢的 Golang 嗎?

這篇文章展示的 Node.js 新擴充套件將顛覆這種情況

你似乎總是不可避免地聽到下一個據稱更快的所謂 Node.js “Web 框架”。是的,我們都知道 Express 很慢,但是存在另一個 “Web 框架”能真正提升 I/O 效能嗎?答案是否定的,除了避免 Express 的執行開銷外,這些新框架在 I/O 效能上並不能做的更多。想要走的更遠,就需要對 Node.js 深入挖掘並重新設計,而不僅僅是在其基礎上加新的一層。

Express 是 Node.js 生態中最古老的所謂“網路框架”之一。它構建在由 Node.js 所提供的開箱即用功能的基礎之上,並提供了一個以 App 為中心的介面來管理 URL、路由、引數、方法等。

當然,它既高效又優雅,但是在效能方面卻不盡人意。最近還浮現出像 Fastify 以及其它數百個類似的網路框架。它們都旨在以較低的效能損失來提供 Express 中的功能。需要指出的是;這是一種效能的損失而不是提升。它們仍然被嚴格限制在 Node.js 所能提供的範圍內,這與其競爭物件相比還遠遠不夠:

[譯] Node.js 會永遠只是慢的 Golang 嗎?

無論是 Fastify 還是其它所謂基於 Node.js 的 “Web 框架”都不能越過 Node.js 的紅線。相對於像 Golang 這樣熱門的選擇方案來說,這樣的上限可以說是相當低了。

幸運的是,Node.js 支援 C++ 擴充套件,Google 的 V8 繫結把 JavaScript 連結到 C++ 並且允許你的 JavaScript 程式碼呼叫其任何行為,甚至是 Node.js 本身並不提供的行為。

這使得擴充套件 JavaScript 成為可能。並提供了全新的視角去探索 JavaScript 的更多用途,使之可以充分發揮 Google V8 的功能,而不用限制於 Node.js “核心開發者” 所認為的足夠好的功能。

釋出新的 µWebSockets.js

我將釋出全新的程式碼 µWebSockets.js,今天就可以在 Github 上看到:github.com/uNetworking…

  • 使用 NPM 安裝 Node.js(儘管託管在 GitHub 上):npm install uNetworking/uWebSockets.js#v15.0.0,可以檢視 NPM 安裝文件。
  • 不需要編譯器;適用於 Linux,macOS 和 Windows。我們從 15.0.0 版本開始並根據 SemVer 遞增。

它是另一個用於 JavaScript 後端的 Web 服務,由大概 6 千行 C 和 C++ 程式碼編寫,在效能方面極大的超過了 Golang。Bitfinex.com 已經把他們的交易介面(REST 和 WebSocket)遷移到了這個服務並且正在逐步將之投入生產。

來自 Bitfinex 的 Paolo Ardoino 特別提到:“這是一個非常酷的專案”。

這項工作得以完成,需要感謝這些贊助者;BitMEX、Bitfinex 和 Coinbase 使這項工作成為可能。多虧了他們,我們現在有了一個新的版本!

請解釋下,這到底是怎麼回事?

這是在新的程式碼許可 Apache 2.0 協議下一個新的專案,是所謂 “uws” 的繼任者。它是一個完整的棧,從系統核心到 Google V8 引擎,為 Node.js 帶來穩定,安全,符合標準,快速且輕量級的 I/O:

[譯] Node.js 會永遠只是慢的 Golang 嗎?

在這個層級的軟體設計中,其中的每一層都只依賴先前的層級,這使得無論是追蹤和修復問題還是擴充套件新的支援變得很簡單。

µSockets 其本身甚至還有 3 個子層級,從 eventingnetworking 再到 crypto,每一個子層只知道前面的層級。這使得更換部件,修復問題和新增替代的實現都不需要更改任何高層的程式碼。

對 OpenSSL 感到疲倦了?那好,通過替換 ssl.c 和 它的 600 行程式碼就可以替換 OpenSSL。其它層甚至都不用知道 SSL 是什麼,因此很容易定位錯誤。

Internal sub layers of µSockets

這和 Node.js 的實現有很大的不同,其設計的實現為“把一切都堆在一起”。在 Node.js 的一個原始檔中,你可以找到 libuv 呼叫,系統呼叫,OpenSSL呼叫,V8 呼叫。這一切都混成一團而沒有試圖去接耦分離使模組獨立。這使得它很難做出任何真正的改變。

簡而言之,為 µWebSockets.js 編碼

以下是一個 µWebSockets.js 的非常簡化的實現,為了簡潔起見省略了很多概念,但是應該能讓你大概知道 µWebSockets.js 是什麼:

[譯] Node.js 會永遠只是慢的 Golang 嗎?

在某些方面相比於 Golang 的 Gorilla Gorilla,在 SSL 和 非 SSL 基礎上它可能表現的更好。也就是說,SSL 基礎上的 JS 程式碼可以比非 SSL 基礎上的 Golang(在某些方面)更快的傳送訊息。我認為這真的很酷。

快速的釋出/訂閱支援

Socket.IO 在很多方面就是 Express 的“實時”等價物。它們都同樣的古老,優雅且受歡迎,但是也非常的慢:

[譯] Node.js 會永遠只是慢的 Golang 嗎?

大部分 Socket.IO 所能幫助你的功能可以歸納為釋出/訂閱,即向包含多個接收者的房間傳送資訊的功能,以及與之對應接收訊息的功能。

Fallbacks 在今天沒有任何意義,因為每個瀏覽器都支援 WebSockets,而且這種情況已經持續很多年了。SSL 的流量不會被企業的代理劫持,並且將像任何 Http 流量一樣通過,所以 SSL 上的 WebSockets 肯定不會被阻塞。你仍然可以有 fallbacks,但是它們毫無意義並且會產生不必要的複雜性。

μWebSockets.js 的一個目標是提供類似於 Socket.IO 中的功能,使之有可能被完全替代,而不是在其頂部包裝一層。但這並不是強制執行任何特定的非標準協議。

大多數公司當遇到 WebSockets 時都在和某些釋出/訂閱的問題作鬥爭。遺憾的是,高效的釋出/訂閱服務並沒有在這次釋出的最後期限提供,但是它馬上就要來了,以非常高的優先順序。它會非常快(基準測試中已經比 Redis 更快了)。注意!

現在發生了什麼?

優化,新增特性和修正錯誤。剛開始開發,可能不能夠完全適應,所以需要有一些相關的介紹。請記住,它是一個由三個不同的倉庫組成包含成千上萬行程式碼的大型專案:

一些在 I/O 上有巨大壓力的公司在使用這個專案。穩定性和安全性(自然且明顯的)是這個專案的最高優先順序。記住要在早期的釋出版本中報告穩定性方面的問題,因為這個釋出版本是包含大量更改的大版本。

如果你作為一家公司認為這個專案是有意義的,並且是有經濟利益的,那麼請確保和我們取得聯絡。我將提供各種各樣的諮詢工作。請聯絡:github.com/alexhultman

謝謝!

如果發現譯文存在錯誤或其他需要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可獲得相應獎勵積分。文章開頭的 本文永久連結 即為本文在 GitHub 上的 MarkDown 連結。


掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章