亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

[譯] Node.js 架構(gòu)概覽

antyiwei / 3571人閱讀

摘要:文件系統(tǒng)請(qǐng)求和相關(guān)請(qǐng)求都會(huì)放進(jìn)這個(gè)線程池處理其他的請(qǐng)求,如網(wǎng)絡(luò)平臺(tái)特性相關(guān)的請(qǐng)求會(huì)分發(fā)給相應(yīng)的系統(tǒng)處理單元參見(jiàn)設(shè)計(jì)概覽。

譯者按:
在 Medium 上看到這篇文章,行文脈絡(luò)清晰,闡述簡(jiǎn)明利落,果斷點(diǎn)下翻譯按鈕。
第一小節(jié)背景鋪陳略啰嗦,可以略過(guò)。剛開(kāi)始我給這部分留了個(gè) blah blah blah 直接翻后面的,翻完之后回頭看,考慮完整性才把第一節(jié)給補(bǔ)上。接下來(lái)的內(nèi)容干貨滿滿,相信對(duì) Node.js 運(yùn)行機(jī)制有興趣的讀者一定會(huì)有所收獲。

原文:Architecture of Node.js’ Internal Codebase
作者:Aren Li

首先,說(shuō)點(diǎn)兒 JavaScript……

StackOverflow 的聯(lián)合創(chuàng)始人 Jeff Atwood 在他著名的編程博客 Coding Horror 上說(shuō):

any application that can be written in JavaScript, will eventually be written in JavaScript.
任何可以用 JavaScript 寫就的應(yīng)用程序,最終都會(huì)以 JavaScript 寫出來(lái)。

JavaScrit 的邊界和影響力在過(guò)去幾年里迅猛發(fā)展,現(xiàn)在已經(jīng)是最流行的編程語(yǔ)言之一。2016 年爆棧網(wǎng)的開(kāi)發(fā)者調(diào)查中,JavaScript 在最流行技術(shù)和最熱門問(wèn)答兩項(xiàng)排名第一,其他方面也名列前茅。

Node.js 是一個(gè)服務(wù)器端 JavaScript 執(zhí)行環(huán)境,提供了底層服務(wù)器功能環(huán)境,包括二進(jìn)制數(shù)據(jù)操作、文件系統(tǒng) I/O、數(shù)據(jù)庫(kù)訪問(wèn)、網(wǎng)絡(luò)訪問(wèn)等。它獨(dú)一無(wú)二的特性使其在現(xiàn)存的多種成熟服務(wù)器語(yǔ)言中脫穎而出,并且經(jīng)過(guò)了業(yè)界領(lǐng)先的科技公司如 Paypal、Tinder、Medium(是的,本文原文的那個(gè)博客系統(tǒng))、LinkedIn 和 Netflex 的實(shí)戰(zhàn)應(yīng)用,甚至這些都發(fā)生在 Node.js 發(fā)布 1.0 之前。

我最近在 StackOverflow 上回答一個(gè)關(guān)于 Node.js 內(nèi)部代碼結(jié)構(gòu)的問(wèn)題,因此而萌生了寫作本文的念頭。

Node.js 的官方文檔其實(shí)講得并不清楚它是什么:

一個(gè)基于 Chrome V8 引擎的 JavaScript 運(yùn)行時(shí)。Node.js 采用事件驅(qū)動(dòng)、非阻塞 I/O 模型……

要理解這段話和它背后的真正力量,我們需要把 Node.js 拆分到組件,了解它們的關(guān)鍵技術(shù),如何交互協(xié)作,最終構(gòu)成了 Node.js 這個(gè)強(qiáng)大的運(yùn)行時(shí)環(huán)境:

組件和第三方依賴

V8:Google 開(kāi)源的高性能 JavaScript 引擎,以 C++ 實(shí)現(xiàn)。這也是集成在 Chrome 中的 JS 引擎。V8 將你寫的 JavaScript 代碼編譯為機(jī)器碼(所以它超級(jí)快)然后執(zhí)行。V8 有多快?看看這個(gè)爆棧網(wǎng)的回答。

libuv:提供異步功能的 C 庫(kù)。它在運(yùn)行時(shí)負(fù)責(zé)一個(gè)事件循環(huán)(Event Loop)、一個(gè)線程池、文件系統(tǒng) I/O、DNS 相關(guān)和網(wǎng)絡(luò) I/O,以及一些其他重要功能。

其他 C/C++ 組件和庫(kù):如 c-ares、crypto (OpenSSL)、http-parser 以及 zlib。這些依賴提供了對(duì)系統(tǒng)底層功能的訪問(wèn),包括網(wǎng)絡(luò)、壓縮、加密等。

應(yīng)用/模塊(Application/Modules):這部分就是所有的 JavaScript 代碼:你的應(yīng)用程序、Node.js 核心模塊、任何 npm install 的模塊,以及你寫的所有模塊代碼。你花費(fèi)的主要精力都在這部分。

綁定(Bindings):Node.js 用了這么多 C/C++ 的代碼和庫(kù),簡(jiǎn)單來(lái)說(shuō),它們性能很好。不過(guò),JavaScript 代碼最后是怎么跟這些 C/C++ 代碼互相調(diào)用的呢?這不是三種不同的語(yǔ)言嗎?確實(shí)如此,而且通常不同語(yǔ)言寫出來(lái)的代碼也不能互相溝通,沒(méi)有 binding 就不行。Binding 是一些膠水代碼,能夠把不同語(yǔ)言綁定在一起使其能夠互相溝通。在 Node.js 中,binding 所做的就是把 Node.js 那些用 C/C++ 寫的庫(kù)接口暴露給 JS 環(huán)境。這么做的目的之一是代碼重用:這些功能已經(jīng)有現(xiàn)存的成熟實(shí)現(xiàn),沒(méi)必要只是因?yàn)閾Q個(gè)語(yǔ)言環(huán)境就重寫一遍,如果橋接調(diào)用一下就足夠的話。另一個(gè)原因是性能:C/C++ 這樣的系統(tǒng)編程語(yǔ)言通常都比其他高階語(yǔ)言(Python、JavaScript、Ruby 等等)性能更高,所以把主要消耗 CPU 的操作以 C/C++ 代碼來(lái)執(zhí)行更加明智。

C/C++ Addons:Binding 僅橋接 Node.js 核心庫(kù)的一些依賴,zlib、OpenSSL、c-ares、http-parser 等。如果你想在應(yīng)用程序中包含其他第三方或者你自己的 C/C++ 庫(kù)的話,需要自己完成這部分膠水代碼。你寫的這部分膠水代碼就稱為 Addon??梢园?Binding 和 Addon 視為連接 JavaScript 代碼和 C/C++ 代碼的橋梁。

術(shù)語(yǔ)

I/O:輸入/輸出(Input/Output)的縮寫,基本上代指那些主要由計(jì)算機(jī) I/O 子系統(tǒng)處理的操作。重 I/O 操作(I/O-bound operations)通常會(huì)牽涉到磁盤或驅(qū)動(dòng)器訪問(wèn),例如數(shù)據(jù)庫(kù)訪問(wèn)或文件系統(tǒng)相關(guān)操作。類似的概念還有重 CPU 操作(CPU-bound)、重內(nèi)存操作(Memory-bound)等等。它們的區(qū)分是根據(jù)系統(tǒng)哪部分性能對(duì)這個(gè)操作有最大的影響。比如對(duì)于某項(xiàng)操作而言,CPU 運(yùn)算能力提高可以帶來(lái)最大的提升,這項(xiàng)操作就屬于重 CPU 操作。

非阻塞/異步:當(dāng)一項(xiàng)請(qǐng)求發(fā)來(lái),應(yīng)用程序會(huì)處理這個(gè)請(qǐng)求,其他操作需要等這個(gè)請(qǐng)求處理完成才能執(zhí)行。這個(gè)流程的問(wèn)題是:當(dāng)大量請(qǐng)求并發(fā)時(shí)每個(gè)請(qǐng)求都需要等待前一個(gè)完成,也就是說(shuō)每個(gè)請(qǐng)求都會(huì)阻塞后面的所有請(qǐng)求,最糟糕的是如果前一個(gè)請(qǐng)求花了很長(zhǎng)時(shí)間(比如從數(shù)據(jù)庫(kù)讀取 3GB 的數(shù)據(jù))后面所有請(qǐng)求都跟著悲劇了。解決辦法可以是引入多處理器和(或)多線程架構(gòu),這些辦法各有優(yōu)劣。Node.js 采用了另一種方式,不再為每個(gè)請(qǐng)求開(kāi)啟一個(gè)新的線程,而是所有請(qǐng)求都在單一的主線程中處理,也只做這么一件事情:處理請(qǐng)求——請(qǐng)求中包含的 I/O 操作如文件系統(tǒng)訪問(wèn)、數(shù)據(jù)庫(kù)讀寫等,都會(huì)轉(zhuǎn)發(fā)給由 libuv 管理的工作線程去執(zhí)行。也就是說(shuō),請(qǐng)求中的 I/O 操作是異步處理的,而非在主線程上進(jìn)行。這個(gè)辦法就使得主線程從不會(huì)阻塞,因?yàn)樗泻臅r(shí)的任務(wù)都分配到了別處。你需要面對(duì)的只有唯一的主線程,所有 libuv 管理的工作線程都與你隔離開(kāi)來(lái),無(wú)需操心,Node.js 會(huì)處理好那部分。在這個(gè)架構(gòu)之上重 I/O 操作變得格外高效,那些重 CPU、重內(nèi)存的也一樣。Node.js 提供了開(kāi)箱即用的異步 I/O 調(diào)度,還有一些針對(duì)重 CPU 執(zhí)行的處理,不過(guò)這已經(jīng)超出本文話題范疇了。

事件驅(qū)動(dòng):基本上,所有現(xiàn)代系統(tǒng)都是主程序啟動(dòng)完畢之后,對(duì)每個(gè)收到的請(qǐng)求開(kāi)啟一個(gè)進(jìn)程,接下來(lái)根據(jù)不同技術(shù)有不同的處理方式,有時(shí)差異會(huì)大相徑庭。典型的實(shí)現(xiàn)是:針對(duì)一個(gè)請(qǐng)求開(kāi)啟一個(gè)線程,一步接一步執(zhí)行任務(wù)操作,如果某個(gè)操作執(zhí)行緩慢,這個(gè)線程上的后續(xù)操作都會(huì)隨之掛起,直到所有操作完成,返回結(jié)果。而在 Node.js 中,所有的操作都注冊(cè)為一個(gè)事件,等待主程序或者外部請(qǐng)求來(lái)觸發(fā)。

(系統(tǒng))運(yùn)行時(shí):Node.js 運(yùn)行時(shí)是指所有這些代碼(上述所有組件,包括底層和上層)提供給 Node.js 應(yīng)用程序執(zhí)行的環(huán)境。

合體

我們已經(jīng)了解 Node.js 頂層組件各自的概貌,現(xiàn)在看看它們組合在一起的工作流程,可以更透徹地理解整體架構(gòu)以及各部分如何協(xié)作交互。

一個(gè) Node.js 應(yīng)用啟動(dòng)時(shí),V8 引擎會(huì)執(zhí)行你寫的應(yīng)用代碼,保持一份觀察者(注冊(cè)在事件上的處理函數(shù))列表。當(dāng)事件發(fā)生時(shí),它的處理函數(shù)會(huì)被加進(jìn)一個(gè)事件隊(duì)列。只要這個(gè)隊(duì)列還有等待執(zhí)行的事件,事件循環(huán)就會(huì)持續(xù)把事件從隊(duì)列中拿出,放進(jìn)調(diào)用堆棧。需要注意的是,只有當(dāng)前一個(gè)事件處理完畢(調(diào)用堆棧也已經(jīng)清空),事件循環(huán)才會(huì)把下一個(gè)事件放進(jìn)調(diào)用堆棧。

在調(diào)用堆棧中,所有的 I/O 請(qǐng)求都會(huì)轉(zhuǎn)發(fā)給 libuv 處理。libuv 會(huì)維持一個(gè)線程池,包含四個(gè)工作線程(這是默認(rèn)數(shù)量,也可以修改配置增加更多工作線程)。文件系統(tǒng) I/O 請(qǐng)求和 DNS 相關(guān)請(qǐng)求都會(huì)放進(jìn)這個(gè)線程池處理;其他的請(qǐng)求,如網(wǎng)絡(luò)、平臺(tái)特性相關(guān)的請(qǐng)求會(huì)分發(fā)給相應(yīng)的系統(tǒng)處理單元(參見(jiàn) libuv 設(shè)計(jì)概覽)。

安排給線程池的這些 I/O 操作由 Node.js 的底層庫(kù)執(zhí)行,完成之后 libuv 把此事件放回事件隊(duì)列,等待主線程執(zhí)行后續(xù)操作。在 libuv 處理這些異步 I/O 操作期間,主線程不會(huì)等待處理結(jié)果,而是繼續(xù)忙其他事情,只有當(dāng)事件循環(huán)把 libuv 返回的事件放進(jìn)調(diào)用堆棧之后,主線程才會(huì)繼續(xù)處理這個(gè)事件的后續(xù)操作。這就是一個(gè)事件在 Node.js 中執(zhí)行的整個(gè)生命周期。

mbp 曾經(jīng)做過(guò)一個(gè)巧妙的比喻,把 Node.js 看成一家餐廳。我在此借用下他的例子,稍作修改來(lái)闡述下 Node.js 的執(zhí)行情況:

把 Node.js 應(yīng)用程序想象成一家星巴克,一個(gè)訓(xùn)練有素的前臺(tái)服務(wù)生(唯一的主線程)在柜臺(tái)前接受訂單。當(dāng)很多顧客同時(shí)光臨的時(shí)候,他們排隊(duì)(進(jìn)入事件隊(duì)列)等候接待;每當(dāng)服務(wù)生接待一位顧客,服務(wù)生會(huì)把訂單告知給經(jīng)理(libuv),經(jīng)理安排相應(yīng)的專職人員去烹制咖啡(工作線程或者系統(tǒng)特性)。這個(gè)專職人員會(huì)使用不同的原料和咖啡機(jī)(底層 C/C++ 組件)按訂單要求制作咖啡或甜點(diǎn),通常會(huì)有四個(gè)這樣的專職人員保持在崗待命(線程池),高峰期的時(shí)候也可以安排更多(不過(guò)需要在一早就安排人員來(lái)上班,而不能中午臨時(shí)通知)。服務(wù)生把訂單轉(zhuǎn)交給經(jīng)理之后不需要等著咖啡制作完成,而是直接開(kāi)始接待下一位顧客(事件循環(huán)放進(jìn)調(diào)用堆棧的另一個(gè)事件),你可以把當(dāng)前調(diào)用堆棧里的事件看成是站在柜臺(tái)前正在接受服務(wù)的顧客。

當(dāng)咖啡完成時(shí),會(huì)被發(fā)送到顧客隊(duì)列的最后位置,等它移動(dòng)到柜臺(tái)前服務(wù)生會(huì)叫相應(yīng)顧客的名字,顧客就來(lái)取走咖啡(最后這部分在真實(shí)生活中聽(tīng)起來(lái)有點(diǎn)怪,不過(guò)你從程序執(zhí)行的角度理解就比較合乎情理了)。

以上就是 Node.js 的內(nèi)部頂層組件架構(gòu)概覽,以及它的事件循環(huán)機(jī)制。本文依然是非常精簡(jiǎn)概括,還有很多問(wèn)題和細(xì)節(jié)沒(méi)有展開(kāi),如重 CPU 操作的處理、Node.js 設(shè)計(jì)模式等,未來(lái)會(huì)有更多文章闡述這些內(nèi)容(譯注:在 Aren Li 的 Medium 專欄 Yet Another Node.js Blog 里)。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/79914.html

相關(guān)文章

  • 1月份前端資源分享

    摘要:更多資源請(qǐng)文章轉(zhuǎn)自月份前端資源分享視頻前端技術(shù)論壇融合不可錯(cuò)過(guò)的迷你庫(kù)測(cè)試框架實(shí)例教程為你詳細(xì)解讀請(qǐng)求頭的具體含意解析的庫(kù)如果要用前端框架,開(kāi)發(fā)流程是怎樣的與有什么區(qū)別正確使用的方法是什么流程圖插件小如何讓元素只能輸入純文本前端技術(shù)中 更多資源請(qǐng)Star:https://github.com/maidishike... 文章轉(zhuǎn)自:https://github.com/jsfront...

    solocoder 評(píng)論0 收藏0
  • 2017-07-14 前端日?qǐng)?bào)

    摘要:前端日?qǐng)?bào)精選技術(shù)周刊譯文四種使用提升應(yīng)用的方式當(dāng)我們談?wù)撉岸思軜?gòu)時(shí),我們到底在談?wù)撌裁词堑模瑏?lái)了與之爭(zhēng)發(fā)布中文譯是的,來(lái)了掘金第期實(shí)踐總結(jié)個(gè)必備的裝逼技巧掘金年學(xué)習(xí)最好的書籍圓形隨機(jī)分布種事件驅(qū)動(dòng)的架構(gòu)試用知識(shí)總結(jié)個(gè)人文章 2017-07-14 前端日?qǐng)?bào) 精選 SegmentFault 技術(shù)周刊【譯文】四種使用webpack提升Vue應(yīng)用的方式當(dāng)我們談?wù)撉岸思軜?gòu)時(shí),我們到底在談?wù)撌裁矗?..

    lewinlee 評(píng)論0 收藏0
  • 】《精通使用AngularJS開(kāi)發(fā)Web App》(二) --- 框架概覽,雙向數(shù)據(jù)綁定,MVC

    摘要:本書的這一部分將為隨后的章節(jié)打下基礎(chǔ),會(huì)涵蓋模板,模塊化,和依賴注入。本書的小例子中我們會(huì)使用未經(jīng)壓縮的,開(kāi)發(fā)友好的版本,在的上。作用域也可以針對(duì)特定的視圖來(lái)擴(kuò)展數(shù)據(jù)和特定的功能。 上一篇:【譯】《精通使用AngularJS開(kāi)發(fā)Web App》(一) 下一篇:【譯】《精通使用AngularJS開(kāi)發(fā)Web App》(三) 原版書名:Mastering Web Application D...

    geekidentity 評(píng)論0 收藏0
  • node js event loop part 1.1

    原文 先說(shuō)1.1總攬: Reactor模式 Reactor模式中的協(xié)調(diào)機(jī)制Event Loop Reactor模式中的事件分離器Event Demultiplexer 一些Event Demultiplexer處理不了的復(fù)雜I/O接口比如File I/O、DNS等 復(fù)雜I/O的解決方案 未完待續(xù) 前言 nodejs和其他編程平臺(tái)的區(qū)別在于如何去處理I/O接口,我們聽(tīng)一個(gè)人介紹nodejs,總是...

    macg0406 評(píng)論0 收藏0
  • 那些年,我的前端/Java后端書單

    摘要:全文為這些年,我曾閱讀深入理解過(guò)或正在閱讀學(xué)習(xí)即將閱讀的一些優(yōu)秀經(jīng)典前端后端書籍。當(dāng)然,如果您喜歡這篇文章,可以動(dòng)手點(diǎn)點(diǎn)贊或者收藏。 全文為這些年,我曾閱讀、深入理解過(guò)(或正在閱讀學(xué)習(xí)、即將閱讀)的一些優(yōu)秀經(jīng)典前端/Java后端書籍。全文為純?cè)瓌?chuàng),且將持續(xù)更新,未經(jīng)許可,不得進(jìn)行轉(zhuǎn)載。當(dāng)然,如果您喜歡這篇文章,可以動(dòng)手點(diǎn)點(diǎn)贊或者收藏。 基礎(chǔ) 基礎(chǔ)書籍 進(jìn)階 進(jìn)階階段,深入學(xué)習(xí)的書...

    fxp 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

antyiwei

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<