摘要:單線程使用單線程來運行,而不是向之類的其它服務(wù)器,每個請求將生產(chǎn)一個線程,這種方法避免了上下文切換和內(nèi)存中的大量執(zhí)行堆棧,這也是和其它服務(wù)器為解決上一個年,著名的并發(fā)連接問題而采用的方法。
當(dāng)我們學(xué)習(xí)一項新的事物的時候,我們首先要知道它來自哪里?它是什么?能做什么或者換句話說,能解決什么問題?沒有一樣?xùn)|西是最好的,是可以替代所有的,但在某一領(lǐng)域它是最適合的,正如 Node.js 它可能是某些程序員苦苦追尋的東西,也可能是某些程序員不會去關(guān)心的東西。本文主要為您介紹 Node.js 的背景及它能做什么,擅長什么,不會涉及到復(fù)雜的代碼層面的知識講解,如果你覺得自己很熟悉了,也可以忽略它。
作者簡介:五月君,Nodejs Developer,熱愛技術(shù)、喜歡分享的 90 后青年,公眾號「Nodejs技術(shù)?!梗珿ithub 開源項目 https://www.nodejs.red
文末附上筆者最近整理的 Node.js 技術(shù)棧學(xué)習(xí)指南路線圖 供大家學(xué)習(xí)參考!
背景介紹Node.js? is a JavaScript runtime built on Chrome"s V8 JavaScript engine. 這是來自 Node.js 官網(wǎng) https://nodejs.org/en/ 的一段介紹,翻譯成中文意為 Node.js 是一個基于 Chrome V8 引擎的 JavaScript 運行環(huán)境。這里重點幾個關(guān)鍵詞 V8、JavaScript 后續(xù)會講解,從這里可以看出 Node.js 并不是一門新的編程語言,做為初學(xué)者這點先要弄清楚,它是 JavaScript 的運行環(huán)境,更進一步的說是在服務(wù)端的運行環(huán)境,因此這里的編程語言指的是 JavaScript。
時間回歸到 2009 年,在當(dāng)時 JavaScript 還是一個跑在瀏覽器環(huán)境里的一門腳本語言,當(dāng)時的筆者還是一名高中生,接觸的編程語言是 VB 并不知 JavaScript 為何物,但隨后接觸 JavaScript 之后了解到這之前用它可以寫一些瀏覽器腳本,做一些動態(tài)特效,主要用于前端頁面交互。在 2009 這一時間線之后 Javascript 不只運行于瀏覽器,還可以運行于服務(wù)端,簡直打通了前端與后端的任督二脈,當(dāng)然這要歸功于 Node.js 之父 Ryan Dahl。一度認(rèn)為這是很偉大的,在眾多編程語言里,為什么會選擇 JavaScript 呢?且看下面介紹。
為什么是 JavaScript?Node.js 使用了一個事件驅(qū)動、非阻塞式 I/O 的模型,使其輕量又高效。這是來自于 Node.js 的另一個介紹,關(guān)鍵詞 事件驅(qū)動、非阻塞式 I/O 因此,在基于這些條件之下 Node.js 作者 Ryan Dahl 在評估了 C、Lua、Haskell、Ruby、JavaScript 等語言之后,最終選擇了 JavaScript,為什么呢?
JavaScript 是一個單線程的語言,單線程的優(yōu)點是不會像 Java 這些多線程語言在編程時出現(xiàn)線程同步、線程鎖問題同時也避免了上下文切換帶來的性能開銷問題,那么其實在瀏覽器環(huán)境也只能是單線程,可以想象一下多線程對同一個 DOM 進行操作是什么場景?不是亂套了嗎?那么單線程可能你會想到的一個問題是,前面一個執(zhí)行不完,后面不就卡住了嗎?當(dāng)然不能這樣子的,JavaScript 是一種采用了事件驅(qū)動、異步回調(diào)的模式,另外 JavaScript 在服務(wù)端不存在什么歷史包袱,在虛擬機上由于又有了 Chrome V8 的支持,使得 JavaScript 成為了 Node.js 的首選語言。
為什么選擇 JavaScript 作者 Ryan Dahl 應(yīng)該是最有發(fā)言權(quán)的,這里查了一些資料及參考了 深入淺出 Node.js 一書,供大家有個初步的認(rèn)知。
Node.js 架構(gòu)Node.js 由 Libuv、Chrome V8、一些核心 API 構(gòu)成,如下圖所示:
以上展示了 Node.js 的構(gòu)成,下面做下簡單說明:
Node Standard Library:Node.js 標(biāo)準(zhǔn)庫,對外提供的 JavaScript 接口,例如模塊 http、buffer、fs、stream 等
Node bindings:這里就是 JavaScript 與 C++ 連接的橋梁,對下層模塊進行封裝,向上層提供基礎(chǔ)的 API 接口。
V8:Google 開源的高性能 JavaScript 引擎,使用 C++ 開發(fā),并且應(yīng)用于谷歌瀏覽器。如果您感興趣想學(xué)習(xí)更多的 V8 引擎知識,請訪問 What is V8?
Libuv:是一個跨平臺的支持事件驅(qū)動的 I/O 庫。它是使用 C 和 C++ 語言為 Node.js 所開發(fā)的,同時也是 I/O 操作的核心部分,例如讀取文件和 OS 交互。來自一份 Libuv 的中文教程
C-ares:C-ares 是一個異步 DNS 解析庫
Low-Level Components:提供了 http 解析、OpenSSL、數(shù)據(jù)壓縮(zlib)等功能。
以上只是做一個初步的認(rèn)知,如果你想深入了解 Node.js 那么多每個點都是值得你深入研究的。
來自 stack overflow 的一個參考:which-is-correct-node-js-architecture
Node.js 特點在了解了 Node.js 的一些背景及架構(gòu)模型之后,已經(jīng)解決了它來自哪里?是什么?這個問題,現(xiàn)在我們來看看能解決什么問題?它適合做什么?
在這之前不知道您有沒有聽說過,Node.js 很擅長 I/O 密集型任務(wù),應(yīng)對一些 I/O 密集型的高并發(fā)場景還是很有優(yōu)勢的,事實也如此,這也是它的定位:提供一種簡單安全的方法在 JavaScript 中構(gòu)建高性能和可擴展的網(wǎng)絡(luò)應(yīng)用程序。
單線程
Node.js 使用單線程來運行,而不是向 Apache HTTP 之類的其它服務(wù)器,每個請求將生產(chǎn)一個線程,這種方法避免了 CPU 上下文切換和內(nèi)存中的大量執(zhí)行堆棧,這也是 Nginx 和其它服務(wù)器為解決 “上一個 10 年,著名的 C10K 并發(fā)連接問題” 而采用的方法。
非阻塞 I/O
Node.js 避免了由于需要等待輸入或者輸出(數(shù)據(jù)庫、文件系統(tǒng)、Web服務(wù)器...)響應(yīng)而造成的 CPU 時間損失,這得益于 Libuv 強大的異步 I/O。
事件驅(qū)動編程
事件與回調(diào)在 JavaScript 中已是屢見不鮮,同時這種編程對于習(xí)慣同步思路的同學(xué)來說可能一時很難理解,但是這種編程模式,確是一種高性能的服務(wù)模型。Node.js 與 Nginx 均是基于事件驅(qū)動的方式實現(xiàn),不同之處在于 Nginx 采用純 C 進行編寫,僅適用于 Web 服務(wù)器,在業(yè)務(wù)處理方面 Node.js 則是一個可擴展、高性能的平臺。
跨平臺
起初 Node.js 只能運行于 Linux 平臺,在 v0.6.0 版本后得益于 Libuv 的支持可以在 Windows 平臺運行。
Node.js 適用于什么講了這么多那么談下 Node.js 適合什么場景?
I/O 密集型場景
Node.js 的優(yōu)勢主要在于事件循環(huán),非阻塞異步 I/O,只開一個線程,不會每個請求過來我都去創(chuàng)建一個線程,從而產(chǎn)生資源開銷。
ResutFul API
通常我們可以使用 Node.js 來做為中間層,負(fù)責(zé)組裝數(shù)據(jù)提供 API 接口給到前端調(diào)用,這些數(shù)據(jù)源可能來自第三方接口或者數(shù)據(jù)庫,例如,以前可能我們通過后端 Java、PHP 等其它語言來做,現(xiàn)在我們前端工程師通過 Node.js 即可完成,后端則可以更專注于業(yè)務(wù)開發(fā)。
既然提到了 ResultFul API,順便推薦一個去哪兒開源的 API 管理工具 YAPI:https://github.com/YMFE/yapi 使用的 Node.js 進行開發(fā)的(聲明下這里不是打廣告,只是這個用起來真的很贊!忍不住向給大家推薦!)。
RPC 服務(wù)
RPC(Remote Procedure Call)中文名「遠(yuǎn)程過程調(diào)用」,也許你對它很陌生,但是在當(dāng)今微服務(wù)模式下,我們可能是針對功能或者具體的業(yè)務(wù)形態(tài)進行服務(wù)化,那么服務(wù)之間的通信一種常見的模式我們都知道通過 HTTP 來實現(xiàn),了解網(wǎng)絡(luò)模型的同學(xué)可能知道,如果我們現(xiàn)在通過 TCP 的方式是不是會更高效呢?
當(dāng)然是的,HTTP 屬于應(yīng)用層協(xié)議,在這之下就是傳輸層,顯然以 TCP 形式是很有優(yōu)勢的,RPC 服務(wù)也就是采用的 TCP,現(xiàn)在出名的 RPC 服務(wù)例如,Google 的 gRPC、阿里的 Dubble。
基礎(chǔ)工具
可以做為基礎(chǔ)工具,前端領(lǐng)域中的編譯器、構(gòu)建工具、搭建腳手架等。比較出名的例如 Webpack、Gulp 都是很成功的。
論壇社區(qū)
Nodeclub 是使用 Node.js 和 MongoDB 開發(fā)的社區(qū)系統(tǒng),界面優(yōu)雅,功能豐富,小巧迅速,可以用它搭建自己的社區(qū)。Cnode 社區(qū)就是一個成功的例子,Cnode 地址:https://cnodejs.org/
https://github.com/cnodejs/nodeclub
Backend For Frontend
Backend For Frontend,簡稱 BFF,服務(wù)于前端的后端,并非是一種新技術(shù)只是一種邏輯上的分層,在這一層我們可以做一些資源的整合,例如:原先前端需要從三個不同的地方來獲取資源,那么,有了這一層之后,我們是不是可以做個聚合,統(tǒng)一處理之后返回給前端,同時也不授后端系統(tǒng)的變遷,導(dǎo)致也要去更改。
Serverless
這將是未來經(jīng)常會聽到的一個詞,ServerLess 是一種 “無服務(wù)器架構(gòu)”,它不需要開發(fā)者去關(guān)心運維、流量處理這些工作,開發(fā)者則可以更關(guān)注于業(yè)務(wù)本身。
函數(shù)即服務(wù),那么寫一個函數(shù)就可以實現(xiàn)一個 API 接口給到前端,顯然對開發(fā)工作是減輕了很多,在 JavaScript 中函數(shù)則是一等一的公民,在 ServerLess 這一場景下 Node.js 本身也很輕量級,還是擁有著很大的優(yōu)勢。
Microservices
微服務(wù)也是近兩年一個很火熱的詞,這里提幾個微服務(wù)主要的特點:小型服務(wù)、以獨立進程運行、可以使用不同語言。那么這里則可以根據(jù)業(yè)務(wù)形態(tài)來選擇不同的語言實現(xiàn),Node.js 本身也是很輕量級的,實現(xiàn)起來也很快,在一些 I/O 密集場景還是很適用的。
什么場景選擇什么工具,沒有最好的只有更合適的!
為什么選擇 Node.js談一些個人感受及經(jīng)歷,其實接觸計算機行業(yè)說不晚也不早,在高中階段開始接觸的編程,在接觸 Node.js 之前也學(xué)過很多編程語言,大致曲線是這樣的 VB(這個是在高中時期)、C、C#(.Net)、Java、PHP 這些都是在學(xué)校的時候沒事玩弄的,還有接觸到前端,真的很雜,但沒有一樣精通的,這也是最可怕的,在大三暑假去了北京一家公司在那里實習(xí)了兩個月 PHP,但是之間有遇見做 Node.js 的同學(xué),當(dāng)時很好奇,哇奧,這是什么東東,竟然可以讓 JavaScript 做后端,就是沒見過市面那種。后來簡單的做了了解,回到學(xué)校之后開始學(xué)習(xí) Node.js 網(wǎng)上找各種資料看,陰差陽錯吧,就這樣選擇了 Node.js 直到現(xiàn)在,其實語言只是一種工具,例如在后端中,拋開語言這一層,還有很多東西是需要我們?nèi)ゲ粩鄬W(xué)習(xí)的。
最后一點建議:不要給自己設(shè)定邊界,例如:我一定要學(xué)習(xí) Node.js 或者我一定要學(xué)習(xí) Java 又或者 Python,其實在有條件的情況下可以多接觸一些其它東西,一方面擴展了自己的邊界,另一方面自己也可以從中獲取收益。
Node.js 技術(shù)棧學(xué)習(xí)指南路線圖這是最近畫的一張 Node.js 技術(shù)棧學(xué)習(xí)指南路線圖,從中可以看出拋開語言這一層面,剩下的都是我們要學(xué)習(xí)的。歡迎大家關(guān)注公眾號「Nodejs技術(shù)棧」專注于 Node.js 相關(guān)技術(shù)棧研究分享,若有 Node.js 相關(guān)文章也歡迎大家投稿!共同成長!
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/106385.html
摘要:一個快速計算假設(shè)每個線程可能有一個伴隨的內(nèi)存,運行在具有的系統(tǒng)上,我們理論上最多有個并發(fā)連接,以及線程之間的上下文切換的成本。通過避免這一切,實現(xiàn)了超過個并發(fā)連接的可伸縮性級別作為概念驗證。 通過近期的面試,我認(rèn)識到自己的學(xué)習(xí)方法還是有問題,面百度的時候面試官問我,為什么要用node,為什么不用php,對于只學(xué)過node幾天的我當(dāng)時就楞了,大概想到單線程事件輪詢和多線程,后來面試官告訴...
摘要:就在幾周前,我正在和一個朋友談話,他不經(jīng)意間提到,你永遠(yuǎn)都不會在生產(chǎn)中直接使用來運行程序。我強烈點頭,表示我也不會在生產(chǎn)中直接運行,原因可能每個人都知道。首先,讓我們弄清楚永遠(yuǎn)不要在生產(chǎn)中直接通過運行程序的說法。 原文地址:You should never ever run directly against Node.js in production. Maybe. 原文作者:Burke ...
摘要:好,你用就用吧,各種問題自己也不會看文檔問谷歌,成天怨聲載道的不得不吐槽一下現(xiàn)在的年輕人。為什么使用有關(guān)和的糾結(jié)歷史可以去谷歌一下,此處不再啰嗦最根本的原因就是對的支持更好,更新和維護也更勤快。 Tips on Ember 2 對我來說是沒什么計劃性的寫作,我只是把它當(dāng)做是每天工作的總結(jié)日志,一個很重要的目的是為團隊做一些技術(shù)事務(wù)的整理,以幫助一些新人快速成長起來。如果有些內(nèi)容不能滿足...
摘要:現(xiàn)在開始創(chuàng)建一個包并分發(fā)給其他人使用,并確保遵循你迄今為止學(xué)到的標(biāo)準(zhǔn)和最佳實踐。第步實踐對于練習(xí),繼續(xù)編寫單元測試,以完成目前為止所做的實際任務(wù),特別是你在步驟中所做的練習(xí)。 今天的Web開發(fā)與幾年前完全不同,有很多不同的東西可以很容易地阻止任何人進入Web開發(fā)。這是我們決定制作這些循序漸進的視覺指南的原因之一,這些指南展示了更大的圖景,并讓任何人清楚了解他們在網(wǎng)頁開發(fā)中扮演的角色。 ...
摘要:單元測試前端的單元測試目前有兩個比較熱的框架,一個是的方式,一個是。小伙伴們不用急,關(guān)于單元測試這塊,我會找時間寫博客的。首先前端的測試分為兩種,一個是單元測試,另一個就是測試了。? ? ? ? 因為公司項目要用vue框架,所以會用vue-cli來新建項目。用過vue的都知道,要全局安裝vue以及腳手架vue-cli,然后執(zhí)行vue init webpack projectname來新建vu...
閱讀 676·2021-11-24 09:39
閱讀 2343·2021-11-22 13:54
閱讀 2211·2021-09-23 11:46
閱讀 3257·2019-08-30 15:55
閱讀 2692·2019-08-30 15:54
閱讀 2419·2019-08-30 14:18
閱讀 1556·2019-08-29 14:15
閱讀 2745·2019-08-29 13:49