深入理解Node.js事件驅動模型

2021-01-12 網際網路技術精選

本文主要討論如下問題:

Node.js事件驅動模型分析Node.js是如何處理高並發請求的Node.js的缺點介紹

首先對Node.js做個簡單介紹,Node.js是一個基於事件驅動、非阻塞式的I/O模型來實現的服務端JavaScript運行環境,是基於Google的V8引擎來實現的單線程、高性能運行在服務端的JavaScript語言。

01Node.js事件驅動模型分析

理解了上面這張圖,你就理解了Node.js的事件驅動模型。從上圖可以看出如下幾部分:

Application應用層,即JavaScript 交互層,常見的就是 Node.js 的模塊,比如 http,fs等V8這一層是V8引擎層,這一層的主要作用是解析JavaScript,同時和應用層和NodeApi層交互NodeApi為上層模塊提供系統調用,和作業系統進行交互 。Libuv是跨平臺的底層封裝,實現了線程池、事件循環、文件操作等,是 Node.js 實現異步的核心 。在Libuv層維護了一個Event Queue的事件隊列,當有請求過來時,經過Node.js的應用層和NodeApi層將請求作為一個事件放到Event Queue事件隊列中,並設置回調事件函數,然後繼續接受新的請求。

在Libuv層的Event Loop事件循環不斷讀Event Queue中的事件,在讀取事件的過程中如果遇到非阻塞事件,會自已處理,並且在處理完後調用回調函數向上一層返回結果;對於阻塞事件,會委託給後臺線程池來處理,當這些阻塞操作完成後,執行結果與提供的回調函數一起再被放入事件隊列中。當Event Loop再次讀到這個事件時,會再次執行被放到隊列中的事件回調函數,最後將結果返回給上一層。具體流程可以參考下圖:

02Node.js是如何處理高並發請求的

如果你理解了上一個問題,這個問題就很好理解了。如果要總結一下那就是異步非阻塞的編程思想。當遇到比較耗時的操作時,採用異步和非阻塞的方式進入事件隊列,不影響後面請求的執行。事件循環會讀取到這個耗時請求,交給線程池來處理。當這些耗時的操作處理完後會再次進入事件隊列,通過事件循環和回調來將請求結果返回給上一層應用,最後返回給客戶端。通過以上方式減少了高並發時的等待,從而可以從容應對高並發。

03Node.js的缺點介紹

通過以上介紹我們知道了Node.js的事件驅動模型,下面我們將介紹一下Node.js的不足。

Node.js的最大不足就是單線程,同一時間只能服務一個請求。而現在伺服器大多數都是多核CPU,這就造成了CPU的利用率非常低,造成資源的浪費。

Node.js的主線程Event Loop在處理事件隊列中的事件時都是按照事件隊列的順序執行的,在其中一個任務沒有完成之前,其他的回調、監聽器等函數都得不到運行的機會,因為被阻塞的Event Loop沒有機會處理它們。如果出現這種情況,程序執行就會變慢。

相關焦點

  • Node.js 學習筆記:學習規劃 & 認知 Node.js
    Node.js 的特性Node.js 保留了 JavaScript 在瀏覽器端中所使用的大部分 API,Node.js 的作者 Ryan Dahl 並沒有改變這門語言本身的任何執行特性,它的編程模型依舊將基於作用域和原型鏈這些概念,這讓 Node.js 這個 JavaScript
  • Node.JS快速入門
    Node.js是一個事件驅動I/O服務端JavaScript環境,基於Google的V8引擎,V8引擎執行Javascript的速度非常快,性能非常好。js,代碼內容我們在命令提示符下輸入命令node demo1.js ,結果如下:2.2 使用函數我們剛才的例子非常簡單,咱們這裡再看一下函數的使用:我們在命令提示符下輸入命令node demo2.js ,結果如下:2.3 模塊化編程創建demo3_1.js創建demo3_2.js2.4 創建
  • windows下安裝nodejs
    windows下安裝nodejs一、什麼是nodejsNode.js 使用了一個事件驅動、非阻塞式 I/O 的模型。Node 是一個讓 JavaScript 運行在服務端的開發平臺,它讓javascript成為與PHP、Python等服務端語言平起平坐的腳步語言。由大神大神 Ryan Dahl 於2009年開發的。
  • nodejs windows環境下搭建
    目前,Node.js是在前端開發中十分受歡迎,它是一套用來編寫高性能網絡伺服器的JavaScript工具包,官網中介紹:Node.js 是一個基於Chrome JavaScript 運行時建立的一個平臺, 用來方便地搭建快速的 易於擴展的網絡應用; Node.js 藉助事件驅動, 非阻塞I
  • Node.js安裝及環境配置之Windows篇
    Node.js 是一個基於 Chrome V8 引擎的 JavaScript 運行環境。Node.js 使用了一個事件驅動、非阻塞式 I/O 的模型,使其輕量又高效。Node.js 的包管理器 npm,是全球最大的開源庫生態系統。
  • 10分鐘理解 Node.js koa 源碼架構設計
    上下文理解 koa 第一步,搞清楚上下文的作用例如:微信群裡面有人說外面下雪了,你跑到窗邊看到的卻是晴空萬裡,這時你才意識到同樣是 10 月份,他在寒冷的北方,你在酷暑的南方類似的,一次請求會包含用戶的登錄狀態,或者一些Token之類的信息,這些信息就是上下文的一部分,用於確定一次的請求環境Koa 的 Context 把 node
  • [譯]Node.js框架Top10(Top 10 Node JS Framework)
    Top 10 Node JS Framework原文地址為 https://medium.com/issuehunt/top-10-node-js-framework-d768a6e465ff1. Hapi.js這個框架擁有可靠的插件系統。
  • 深入理解Node.js中的垃圾回收和內存洩漏的捕獲
    當然這並不意味著Node.js在性能方面就比其他技術表現的都更差, 因此開發者有必要清晰的理解Node.js是具體如何工作的的。由於這個技術有一個非常扁平的學習曲線, 如果要跟蹤Node.js的運行,通常都比較複雜,因此你需要提前理解它的運行機制,從而避免可能存在的性能損失。一旦出現了問題, 你需要儘快的定位它並進行修復。
  • Node.js和Geddy初學者指南(第一部分)
    如果你開發了web應用很多年的話,你可能已經知道了Node.js。如果你不知道的話,這裡我們將簡單的說明一下:「Node.js是一個基於Chrome javascript runtime的平臺,可以很簡單的創建基於伺服器端的javascript應用。Node.js使用事件驅動,非阻塞的I/O模型,特別適合開發實時的應用。」
  • 「譯」理解 Node.js 的中 Worker Threads
    原文:https://nodesource.com/blog/worker-threads-nodejs理解 Node 的底層對於理解 Workers 是很有必要的。當一個 Node.js 的應用啟動的同時,它會啟動如下模塊:一個進程一個線程事件循環機制JS 引擎實例Node.js 實例一個進程:process 對象是一個全局變量,可在 Node.js 程序中任意地方訪問,並提供當前進程的相關信息。一個線程:單線程意味著在當前進程中同一時刻只有一個指令在執行。
  • Node.js是用來做什麼的?
    Node.js是一個事件驅動I/O服務端JavaScript環境,基於Google的V8引擎,V8引擎執行Javascript的速度非常快,性能非常好。作為一個異步事件驅動的 JavaScript 運行時,Node.js 被設計用來構建可擴展的網絡應用。
  • 系統性學習 Node.js(1)- Node.js 基礎概念
    Node不是一門語言是讓js運行在後端的運行時,並且不包括javascript全集,因為在服務端中不包含DOM和BOM。Node也提供了一些新的模塊例如http,fs模塊等。Node.js 使用了事件驅動、非阻塞式 I/O 的模型,使其輕量又高效。並且 Node.js 的包管理器 npm,是全球最大的開源庫生態系統。
  • centos7編程實踐:安裝nodejs
    2、node.js的優勢2.1、Nodejs語法完全是js語法,只要你懂js基礎就可以學會Nodejs後端開發Node打破了過去JavaScript只能在瀏覽器中運行的局面。前後端編程環境統一,可以大大降低開發成本。
  • 如何安裝Node.js
    如何安裝Node.js 本文分別介紹在Mac, Ubuntu,Centos以及Windows下安裝Node.js.安裝git3 .運行下面的命令行編譯node.jsgit clone git://github.com/joyent/node.git  cd node  .
  • 使用Node.js的Alexa技巧
    package.json這個文件是Node.js生態系統的核心,是理解和使用Node.js、NPM甚至現代JavaScript的一個基本部分。utilities/util.js*具有有用功能的文件。local-debugger.js*用於本地調試我們的技能。errors*包含所有錯誤處理程序的文件夾。intents*包含所有意圖處理程序的文件夾。
  • Node.js在Red Hat OpenShift應用程式運行時的一般可用性
    Node.js加入了現有的受支持運行時間集合,並為開發人員提供了一個事件驅動的非阻塞I / O模型,使其輕量且高效,非常適合跨分布式設備運行的數據密集型實時應用程式。盒子裡有什麼東西?此版本的特性包括Node.js核心運行時版本8.9.4,npm 5.6.0以及相關的任務和增強器,以支持開發人員開始使用Node.js並啟動項目。
  • 深入Node.js的模塊加載機制,手寫require函數
    簡單例子老規矩,講原理前我們先來一個簡單的例子,從這個例子入手一步一步深入原理。總體的代碼都在這個文件裡面:https://github.com/nodejs/node/blob/c6b96895cc74bc6bd658b4c6d5ea152d6e686d20/lib/internal/modules/cjs/loader.js
  • Node.js在大前端領域的應用分析
    關於 node 的使用已經很久了,使用範圍也很廣,似乎有前端的地方就有 node,那麼來思考一個問題,node 到底是用來幹嘛的呢?本文從五個大的方面對該問題進行了解釋。本文不僅僅可以應用場景的分析,完全可以把它當做Node.js高級進階當路線,看看那些你還需要學。
  • Node.js與Django:JavaScript比Python好嗎?
    Node.jsJavaScript的主要優勢在於它在客戶端開發方面的優勢,但Node.js正在通過在伺服器端創建奇蹟來完全相反。Node是一個開源JavaScript運行時環境,用C,C ++和JavaScript編寫,構建於Google V8 JavaScript引擎上,並於2009年發布.Node.js基於事件驅動的非阻塞I / O模型。
  • 如何系統的學習Node.js?
    模型/欄目/分類信息體系:通過欄目和模型綁定,以及不同的模型類型,不同欄目可以實現差異化的功能,輕鬆實現諸如資訊、下載、討論和圖片等功能。通過分類信息和欄目綁定,可以自動建立索引表,輕鬆實現複雜的信息檢索。