在哪些情況下你要使用node?node的應用場景?


1.特點

(1)善於I/O,不善於計算

當應用程序需要處理大量並發的I/O,而在向客戶端發出響應之前,應用程序內部並不需要進行非常復雜的處理的時候,node.js就非常適用。node.js也非常適用與websocket配合,開發長連接的實時交互應用程序。

node.js最擅長的就是任務調度,如果你的業務有很多CPU計算,實際上相當於這個計算阻塞了這個單線程就不適用於node開發。

(2)天生異步

2. nodeJs取舍特點:
         可靠性低
         高性能
         單線程
         異步事件驅動
         非阻塞式IO
         輕量高效

3.應用場景

網站開發
im即時聊天(socket. io)
api(移動端,pc)
HTTP  Proxy
前端構建工具

 

 

Node.js的特點
非阻塞異步io

例如,當在訪問數據庫取得數據的時候,需要一段時間。在傳統的單線程處理機制中,在執行了訪問數據庫代碼之后,整個線程都將暫停下來,等待數據庫返回結果,才能執行后面的代碼。也就是說,I/O阻塞了代碼的執行,極大地降低了程序的執行效率。

由於 Node.js 中采用了非阻塞型I/O機制,因此在執行了訪問數據庫的代碼之后,將立即轉而執行其后面的代碼,把數據庫返回結果的處理代碼放在回調函數中,從而提高了程序的執行效率。

當某個I/O執行完畢時,將以事件的形式通知執行I/O操作的線程,線程執行這個事件的回調函數。為了處理異步I/O,線程必須有事件循環,不斷的檢查有沒有未處理的事件,依次予以處理。

阻塞模式下,一個線程只能處理一項任務,要想提高吞吐量必須通過多線程。而非阻塞模式下,一個線程永遠在執行計算操作,這個線程的CPU核心利用率永遠是100%。所以,這是一種特別有哲理的解決方案:與其人多,但是好多人閑着;還不如一個人玩命,往死里干活兒。

單線程

在 Java、PHP 或者 .net 等服務器端語言中,會為每一個客戶端連接創建一個新的線程。而每個線程需要耗費大約2MB內存。也就是說,理論上,一個8GB內存的服務器可以同時連接的最大用戶數為4000個左右。要讓Web應用程序支持更多的用戶,就需要增加服務器的數量,而 Web 應用程序的硬件成本當然就上升了。

Node.js不為每個客戶連接創建一個新的線程,而僅僅使用一個線程。當有用戶連接了,就觸發一個內部事件,通過非阻塞I/O、事件驅動機制,讓 Node.js 程序宏觀上也是並行的。使用 Node.js ,一個8GB內存的服務器,可以同時處理超過4萬用戶的連接。

另外,單線程帶來的好處,操作系統完全不再有線程創建、銷毀的時間開銷。但是單線程也有很多弊端,會在 Node.js 的弊端詳細講解,請繼續看。

事件驅動

在 Node.js 中,客戶端請求建立連接,提交數據等行為,會觸發相應的事件。在Node.js 中,在一個時刻,只能執行一個事件回調函數,但是在執行一個事件回調函數的中途,又有其他事件產生,可以轉而處理其他事件(比如,又有新用戶連接了),然后返回繼續執行原事件的回調函數,這種處理機制,稱為“事件環”機制。

Node.js 底層是 C++(V8也是C++寫的)。底層代碼中,近半數都用於事件隊列、回調函數隊列的構建。用事件驅動來完成服務器的任務調度,這是鬼才才能想到的。針尖上的舞蹈,用一個線程,擔負起了處理非常多的任務的使命。

 

 

注意這里的事件循環,也可以說是 Node.js 的一個精髓所在,下面引用一段 Node.js 官網的內容

 

引用Node官網中的一段內容:

注意:每個框將被稱為事件循環的“階段”。每個階段都有一個要執行的回調FIFO隊列。雖然每個階段都以其自己的方式特殊,但通常情況下,當事件循環進入給定階段時,它將執行特定於該階段的任何操作,然后在該階段的隊列中執行回調,直到隊列耗盡或最大回調數量為止已執行。當隊列耗盡或達到回調限制時,事件循環將移至下一階段,依此類推。關於事件循環是一個核心點,經常會被面試官考具體執行輸出的問題,大家可以看我的這篇文章

跨平台

起初,Node 只能在 Linux 平台上運行。后來隨着 Node的發展,微軟注意到了它的存在,並投入了一個團隊幫助 Node 實現 Windows 平台的兼容,在v0.6.0版本發布時,Node 已經能夠直接在 Window 平台運行了。Node 是基於libuv實現跨平台的。

Node.js的弊端
單線程帶來的弊端
Node.js中有一個特點就是單線程,它帶來了很多好處,但是它也有弊端,單線程弱點如下。

無法利用多核CPU
錯誤會引起整個應用退出無法繼續調用異步I/O
大量計算占用CPU導致無法繼續調用異步I/O
以上確實是Node的弊端,但是都會有一些對應的解決方案:

弊端1:解決方案

(1)一些管理工具比如pm2,forever 等都可以實現創建多進程解決多核 CPU 的利用率問題。
(2)在v0.8版本之前,實現多進程可以使用child_process
(3)在v0.8版本之后,可以使用cluster模塊,通過主從模式,創建多個工作進程解決多核CPU的利用率問題。
弊端2:解決方案

(1)Nnigx反向代理,負載均衡,開多個進程,綁定多個端口;
(2) 一些管理工具比如pm2,forever 等都可以實現進程監控,錯誤自動重啟等
(3)開多個進程監聽同一個端口,使用Node提供的cluster模塊;
(4)未出現cluster之前,也可以使用child_process,創建多子線程監聽一個端口。
(5)這里說明下,有上面的這些解決方案,但是寫node后端代碼的時候,異常拋出try catch顯得格外有必要。
弊端3:解決方案

(1)可以把大量的密集計算像上面一樣拆分成多個子線程計算
但是如果不允許拆分,想計算100萬的大數據,在一個單線程中,Node確實顯得無能為力,這本身就是V8內存限制的弊端。
說明:child_process與cluster模塊我會單獨拿一篇文章來講。值得開心的是上面這些弊端隨着Node的版本更新,和新的api模塊出現,好像解決了這些弊端。

調試
用過node的人可能第一時間就會想到debug太難了,沒有stack trace,因此調試比較困難。

Node社區中的npm包
Node.js社區有很多包品質良莠不齊、如果你想偷懶而又剛好npm了一個有問題的包你就很麻煩,因為代碼是開源的,只能自己調試了。

Node.js的應用場景
介紹了Node.js的特點和弊端,再說一下Node.js的應用場景。

Node.js適合用來開發什么樣的應用程序呢?

善於I/O,不善於計算。因為Node.js最擅長的就是任務調度,如果你的業務有很多的 CPU 計算,實際上也相當於這個計算阻塞了這個單線程,就不太適合Node開發,但是也不是沒有解決方案,只是說不太適合。

當應用程序需要處理大量並發的I/O,而在向客戶端發出響應之前,應用程序內部並不需要進行非常復雜的處理的時候,Node.js非常適合。Node.js也非常適合與websocket配合,開發長連接的實時交互應用程序。

具體場景可以表現為如下:

第一大類:用戶表單收集系統、后台管理系統、實時交互系統、考試系統、聯網軟件、高並發量的web應用程序;

第二大類:基於web、canvas等多人聯網游戲;

第三大類:基於web的多人實時聊天客戶端、聊天室、圖文直播;

第四大類:單頁面瀏覽器應用程序;

第五大類:操作數據庫、為前端和移動端提供基於json的API;

第六大類,....

哪些大公司在用
雅虎:雅虎開放了Cooktail框架,將YUI3這個前端框架的能力借助Node延伸到了服務器端。
騰訊:將 Node應用到長連接,以提供實時功能。
花瓣網,蘑菇街:通過socket.io實現實時通知。
阿里:主要利用的是並行I/O這個性能,實現高效的分布式,它們自己也出了很多Node框架
LinkedIn:移動網站也是使用的Node
網易:游戲領域對並發和實時要求很高,網易開源了Node的實時框架pomelo
很多教育公司在用Node搭建中台或者直接作為后端
等等...
https://www.php.cn/js-tutorial-409402.html

 

https://blog.csdn.net/weixin_33923762/article/details/92709161

 

 

其特點為:

  1. 它是一個Javascript運行環境

  2. 依賴於Chrome V8引擎進行代碼解釋

  3. 事件驅動

  4. 非阻塞I/O

  5. 輕量、可伸縮,適於實時數據交互應用

  6. 單進程,單線程

二. NodeJS帶來的對系統瓶頸的解決方案

它的出現確實能為我們解決現實當中系統瓶頸提供了新的思路和方案,下面我們看看它能解決什么問題。

  1. 並發連接

舉個例子,想象一個場景,我們在銀行排隊辦理業務,我們看看下面兩個模型。

(1)系統線程模型:

系統線程模型

這種模型的問題顯而易見,服務端只有一個線程,並發請求(用戶)到達只能處理一個,其余的要先等待,這就是阻塞,正在享受服務的請求阻塞后面的請求了。

(2)多線程、線程池模型:

多線程、線程池模型

這個模型已經比上一個有所進步,它調節服務端線程的數量來提高對並發請求的接收和響應,但並發量高的時候,請求仍然需要等待,它有個更嚴重的問題。到代碼層面上來講,我們看看客戶端請求與服務端通訊的過程:

客戶端請求與服務端通訊的過程

服務端與客戶端每建立一個連接,都要為這個連接分配一套配套的資源,主要體現為系統內存資源,以PHP為例,維護一個連接可能需要20M的內存。這就是為什么一般並發量一大,就需要多開服務器。

那么NodeJS是怎么解決這個問題的呢?我們來看另外一個模型,想象一下我們在快餐店點餐吃飯的場景。

(3)異步、事件驅動模型

異步、事件驅動模型

我們同樣是要發起請求,等待服務器端響應;但是與銀行例子不同的是,這次我們點完餐后拿到了一個號碼,拿到號碼,我們往往會在位置上等待,而在我們后面的請求會繼續得到處理,同樣是拿了一個號碼然后到一旁等待,接待員能一直進行處理。

等到飯菜做號了,會喊號碼,我們拿到了自己的飯菜,進行后續的處理(吃飯)。這個喊號碼的動作在NodeJS中叫做回調(Callback),能在事件(燒菜,I/O)處理完成后繼續執行后面的邏輯(吃飯),這體現了NodeJS的顯著特點,異步機制、事件驅動整個過程沒有阻塞新用戶的連接(點餐),也不需要維護已經點餐的用戶與廚師的連接。

基於這樣的機制,理論上陸續有用戶請求連接,NodeJS都可以進行響應,因此NodeJS能支持比Java、PHP程序更高的並發量雖然維護事件隊列也需要成本,再由於NodeJS是單線程,事件隊列越長,得到響應的時間就越長,並發量上去還是會力不從心。

總結一下NodeJS是怎么解決並發連接這個問題的:更改連接到服務器的方式,每個連接發射(emit)一個在NodeJS引擎進程中運行的事件(Event),放進事件隊列當中,而不是為每個連接生成一個新的OS線程(並為其分配一些配套內存)。

  1. I/O阻塞

NodeJS解決的另外一個問題是I/O阻塞,看看這樣的業務場景:需要從多個數據源拉取數據,然后進行處理。

(1)串行獲取數據,這是我們一般的解決方案,以PHP為例I/O阻塞-PHP為例

假如獲取profile和timeline操作各需要1S,那么串行獲取就需要2S。

(2)NodeJS非阻塞I/O,發射/監聽事件來控制執行過程

非I/O阻塞-PHP為例

NodeJS遇到I/O事件會創建一個線程去執行,然后主線程會繼續往下執行的,因此,拿profile的動作觸發一個I/O事件,馬上就會執行拿timeline的動作,兩個動作並行執行,假如各需要1S,那么總的時間也就是1S。它們的I/O操作執行完成后,發射一個事件,profile和timeline,事件代理接收后繼續往下執行后面的邏輯,這就是NodeJS非阻塞I/O的特點。

總結一下:Java、PHP也有辦法實現並行請求(子線程),但NodeJS通過回調函數(Callback)和異步機制會做得很自然。

三. NodeJS的優缺點

優點:1. 高並發(最重要的優點)

  1. 適合I/O密集型應用

缺點:1. 不適合CPU密集型應用;CPU密集型應用給Node帶來的挑戰主要是:由於JavaScript單線程的原因,如果有長時間運行的計算(比如大循環),將會導致CPU時間片不能釋放,使得后續I/O無法發起;

解決方案:分解大型運算任務為多個小任務,使得運算能夠適時釋放,不阻塞I/O調用的發起;

  1. 只支持單核CPU,不能充分利用CPU

  2. 可靠性低,一旦代碼某個環節崩潰,整個系統都崩潰

原因:單進程,單線程

解決方案:(1)Nnigx反向代理,負載均衡,開多個進程,綁定多個端口;

(2)開多個進程監聽同一個端口,使用cluster模塊;

  1. 開源組件庫質量參差不齊,更新快,向下不兼容

  2. Debug不方便,錯誤沒有stack trace

四. 適合NodeJS的場景

  1. RESTful API

這是NodeJS最理想的應用場景,可以處理數萬條連接,本身沒有太多的邏輯,只需要請求API,組織數據進行返回即可。它本質上只是從某個數據庫中查找一些值並將它們組成一個響應。由於響應是少量文本,入站請求也是少量的文本,因此流量不高,一台機器甚至也可以處理最繁忙的公司的API需求。

  1. 統一Web應用的UI層

目前MVC的架構,在某種意義上來說,Web開發有兩個UI層,一個是在瀏覽器里面我們最終看到的,另一個在server端,負責生成和拼接頁面。

不討論這種架構是好是壞,但是有另外一種實踐,面向服務的架構,更好的做前后端的依賴分離。如果所有的關鍵業務邏輯都封裝成REST調用,就意味着在上層只需要考慮如何用這些REST接口構建具體的應用。那些后端程序員們根本不操心具體數據是如何從一個頁面傳遞到另一個頁面的,他們也不用管用戶數據更新是通過Ajax異步獲取的還是通過刷新頁面。

  1. 大量Ajax請求的應用

例如個性化應用,每個用戶看到的頁面都不一樣,緩存失效,需要在頁面加載的時候發起Ajax請求,NodeJS能響應大量的並發請求。  總而言之,NodeJS適合運用在高並發、I/O密集、少量業務邏輯的場景。

五. 結尾

其實NodeJS能實現幾乎一切的應用,我們考慮的點只是適不適合用它來做。

NodeJs的優勢:現在的很多的服務器端的語言(PHP,JAVA,ASP.net),有什么問題呢,現在的服務器端的語言在用戶訪問服務器時,為每個用戶鏈接創建了一個線程,但每個線程大約要耗費2M的內存,如果一個8G內存的服務器,也就能鏈接4000個左右的用戶,如果用戶的鏈接數較大,就必須增加服務器的數量,而且現在用戶的鏈接方式有很多(如app,網頁同時訪問),這就又涉及到服務器共享的問題,所以服務器怎么支持最大的同時鏈接用戶量就成了一個問題;NodeJS修改了客戶端到服務器端的鏈接方法,解決了這個問題,他不在為每個客戶端創建一個新的線程,而是為每個客戶端鏈接出發一個NodeJs內部進行處理的事件,所以NodeJS具備同時處理多達幾萬個用戶的客戶端鏈接的能力;NodeJS適合開發的應用程序:當應用程序需要處理大量並發的輸入/輸出,而在向客戶端發出響應之前,應用程序內部並不需要進行非常復雜的處理的時候,我們應該考慮使用NodeJs來進行應用程序的開發,例如:1、聊天服務器:如果聊天的人很多,用戶的與服務器之間的並發鏈接量很大,但是服務器端的數據處理並不復雜;2、綜合類服務網站和電子商務網站的服務器:在這類網站中的服務器端,往往可能每秒存內可以接受多達上千條的數據並且需要將這些數據寫入數據庫中,NodeJs可以通過其隊列機制將這些數據迅速寫入緩存區中,然后再通過每一個單獨的處理從緩存區中取出這些數據並將其寫入數據庫中,如果是其他的服務器(如Apache服務器或Tomcat服務器)的話,由於這些服務器采用的是阻塞型I/O機制,因此每條數據寫入到數據庫中都要等待一段時間(等上一條寫完,才能寫下一條),但是NodeJs使用的是非阻塞的I/O機制,因此可以實現這些數據到數據庫中的寫入,而不必再為每條數據的寫入而等待一段時間


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM