您好,登錄后才能下訂單哦!
這篇文章主要介紹Nodejs的運行原理是什么,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
前言
Node目前處境稍顯尷尬,很多語言都已經擁有異步非阻塞的能力。阿里的思路是比較合適的,但是必須要注意,絕對不能讓node做太多的業務邏輯,他只適合接收生成好的數據,然后或渲染后,或直接發送到客戶端。
為什么nodejs 還可以成為主流技術哪?
是因為nodejs 對于大前端來說還是非常重要的技術!!!如果你理解nodejs 的編程原理,很容易就會理解angularjs,reactjs 和vuejs 的設計原理。
NodeJS
Node是一個服務器端JavaScript解釋器,用于方便地搭建響應速度快、易于擴展的網絡應用。Node使用事件驅動,非阻塞I/O 模型而得以輕量和高效,非常適合在分布式設備上運行數據密集型的實時應用。
Node是一個可以讓JavaScript運行在瀏覽器之外的平臺。它實現了諸如文件系統、模塊、包、操作系統 API、網絡通信等Core JavaScript沒有或者不完善的功能。歷史上將JavaScript移植到瀏覽器外的計劃不止一個,但Node.js 是最出色的一個。
相關推薦:《nodejs 教程》
V8引擎
V8 JavaScript引擎是Google用于其Chrome瀏覽器的底層JavaScript引擎。很少有人考慮JavaScript在客戶機上實際做了些什么!
實際上,JavaScript引擎負責解釋并執行代碼。Google使用V8創建了一個用C++編寫的超快解釋器,該解釋器擁有另一個獨特特征;您可以下載該引擎并將其嵌入任何應用程序。V8 JavaScript引擎并不僅限于在一個瀏覽器中運行。
因此,Node實際上會使用Google編寫的V8 JavaScript引擎,并將其重建為可在服務器上使用。
事件驅動
在我們使用Java,PHP等語言實現編程的時候,我們面向對象編程是完美的編程設計,這使得他們對其他編程方法不屑一顧。卻不知大名鼎鼎Node使用的卻是事件驅動編程的思想。那什么是事件驅動編程。
事件驅動編程,為需要處理的事件編寫相應的事件處理程序。代碼在事件發生時執行。
為需要處理的事件編寫相應的事件處理程序。要理解事件驅動和程序,就需要與非事件驅動的程序進行比較。實際上,現代的程序大多是事件驅動的,比如多線程的程序,肯定是事件驅動的。早期則存在許多非事件驅動的程序,這樣的程序,在需要等待某個條件觸發時,會不斷地檢查這個條件,直到條件滿足,這是很浪費cpu時間的。而事件驅動的程序,則有機會釋放cpu從而進入睡眠態(注意是有機會,當然程序也可自行決定不釋放cpu),當事件觸發時被操作系統喚醒,這樣就能更加有效地使用cpu。
來看一張簡單的事件驅動模型(uml):
事件驅動模型主要包含3個對象:事件源、事件和事件處理程序。
? 事件源:產生事件的地方(html元素)
? 事件:點擊/鼠標操作/鍵盤操作等等
? 事件對象:當某個事件發生時,可能會產生一個事件對象,該時間對象會封裝好該時間的信息,傳遞給事件處理程序
? 事件處理程序:響應用戶事件的代碼
運行原理
當我們搜索Node.js時,奪眶而出的關鍵字就是 “單線程,異步I/O,事件驅動”,應用程序的請求過程可以分為倆個部分:CPU運算和I/O讀寫,CPU計算速度通常遠高于磁盤讀寫速度,這就導致CPU運算已經完成,但是不得不等待磁盤I/O任務完成之后再繼續接下來的業務。
所以I/O才是應用程序的瓶頸所在,在I/O密集型業務中,假設請求需要100ms來完成,其中99ms化在I/O上。如果需要優化應用程序,讓他能同時處理更多的請求,我們會采用多線程,同時開啟100個、1000個線程來提高我們請求處理,當然這也是一種可觀的方案。
但是由于一個CPU核心在一個時刻只能做一件事情,操作系統只能通過將CPU切分為時間片的方法,讓線程可以較為均勻的使用CPU資源。但操作系統在內核切換線程的同時也要切換線程的上線文,當線程數量過多時,時間將會被消耗在上下文切換中。所以在大并發時,多線程結構還是無法做到強大的伸縮性。
那么是否可以另辟蹊徑呢?!我們先來看看單線程,《深入淺出Node》一書提到 “單線程的最大好處,是不用像多線程編程那樣處處在意狀態的同步問題,這里沒有死鎖的存在,也沒有線程上下文切換所帶來的性能上的開銷”,那么一個線程一次只能處理一個請求豈不是無稽之談,先讓我們看張圖:
Node.js的單線程并不是真正的單線程,只是開啟了單個線程進行業務處理(cpu的運算),同時開啟了其他線程專門處理I/O。當一個指令到達主線程,主線程發現有I/O之后,直接把這個事件傳給I/O線程,不會等待I/O結束后,再去處理下面的業務,而是拿到一個狀態后立即往下走,這就是“單線程”、“異步I/O”。
I/O操作完之后呢?Node.js的I/O 處理完之后會有一個回調事件,這個事件會放在一個事件處理隊列里頭,在進程啟動時node會創建一個類似于While(true)的循環,它的每一次輪詢都會去查看是否有事件需要處理,是否有事件關聯的回調函數需要處理,如果有就處理,然后加入下一個輪詢,如果沒有就退出進程,這就是所謂的“事件驅動”。這也從Node的角度解釋了什么是”事件驅動”。
在node.js中,事件主要來源于網絡請求,文件I/O等,根據事件的不同對觀察者進行了分類,有文件I/O觀察者,網絡I/O觀察者。事件驅動是一個典型的生產者/消費者模型,請求到達觀察者那里,事件循環從觀察者進行消費,主線程就可以馬不停蹄的只關注業務不用再去進行I/O等待。
優點
Node 公開宣稱的目標是 “旨在提供一種簡單的構建可伸縮網絡程序的方法”。我們來看一個簡單的例子,在 Java和 PHP 這類語言中,每個連接都會生成一個新線程,每個新線程可能需要 2 MB 的配套內存。在一個擁有 8 GB RAM 的系統上,理論上最大的并發連接數量是 4,000 個用戶。隨著您的客戶群的增長,如果希望您的 Web 應用程序支持更多用戶,那么,您必須添加更多服務器。所以在傳統的后臺開發中,整個 Web 應用程序架構(包括流量、處理器速度和內存速度)中的瓶頸是:服務器能夠處理的并發連接的最大數量。這個不同的架構承載的并發數量是不一致的。
而Node的出現就是為了解決這個問題:更改連接到服務器的方式。在Node 聲稱它不允許使用鎖,它不會直接阻塞 I/O 調用。Node在每個連接發射一個在 Node 引擎的進程中運行的事件,而不是為每個連接生成一個新的 OS 線程(并為其分配一些配套內存)。
缺點
如上所述,nodejs的機制是單線程,這個線程里面,有一個事件循環機制,處理所有的請求。在事件處理過程中,它會智能地將一些涉及到IO、網絡通信等耗時比較長的操作,交由worker threads去執行,執行完了再回調,這就是所謂的異步IO非阻塞吧。但是,那些非IO操作,只用CPU計算的操作,它就自己扛了,比如算什么斐波那契數列之類。它是單線程,這些自己扛的任務要一個接著一個地完成,前面那個沒完成,后面的只能干等。因此,對CPU要求比較高的CPU密集型任務多的話,就有可能會造成號稱高性能,適合高并發的node.js服務器反應緩慢。
適合場景
1、RESTful API
這是適合 Node 的理想情況,因為您可以構建它來處理數萬條連接。它仍然不需要大量邏輯;它本質上只是從某個數據庫中查找一些值并將它們組成一個響應。由于響應是少量文本,入站請求也是少量的文本,因此流量不高,一臺機器甚至也可以處理最繁忙的公司的 API 需求。
2、實時程序
比如聊天服務
聊天應用程序是最能體現 Node.js 優點的例子:輕量級、高流量并且能良好的應對跨平臺設備上運行密集型數據(雖然計算能力低)。同時,聊天也是一個非常值得學習的用例,因為它很簡單,并且涵蓋了目前為止一個典型的 Node.js 會用到的大部分解決方案。
3、單頁APP
ajax很多。現在單頁的機制似乎很流行,比如phonegap做出來的APP,一個頁面包打天下的例子比比皆是。
總而言之,NodeJS適合運用在高并發、I/O密集、少量業務邏輯的場景
以上是“Nodejs的運行原理是什么”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。