400-650-7353
Node是什么
官方解釋:Node.js 是一個(gè)基于 Chrome V8 引擎的 JavaScript 運(yùn)行時(shí)。 也就是說(shuō)Node.js不是一種獨(dú)立的語(yǔ)言,與PHP、JSP、Python的“既是語(yǔ)言,也是平臺(tái)”不同,Node.js的語(yǔ)法是Ecmascript,運(yùn)行在谷歌V8引擎上。
與PHP、JSP等相比(PHP、JSP、.net都需要運(yùn)行在服務(wù)器程序上,Apache、Nginx、IIS。),Node.js跳過(guò)了Apache、Nginx、IIS等HTTP服務(wù)器,它自己不用建設(shè)在任何服務(wù)器軟件之上,可以很方便地任意擴(kuò)展web服務(wù)器。Node.js的許多設(shè)計(jì)理念與經(jīng)典架構(gòu)(LAMP = Linux + Apache + MySQL + PHP)有著很大的不同,可以提供強(qiáng)大的伸縮能力。
Node的特點(diǎn)
Node平臺(tái)的特點(diǎn)也決定了它可以開發(fā)出什么產(chǎn)品。
1.單線程
在Java、PHP或者.net等服務(wù)器端語(yǔ)言中,會(huì)為每一個(gè)客戶端連接創(chuàng)建一個(gè)新的線程。而每個(gè)線程需要耗費(fèi)大約2MB內(nèi)存。也就是說(shuō),理論上,一個(gè)8GB內(nèi)存的服務(wù)器可以同時(shí)連接的最大用戶數(shù)為4000個(gè)左右。要讓W(xué)eb應(yīng)用程序支持更多的用戶,就需要增加服務(wù)器的數(shù)量,而Web應(yīng)用程序的硬件成本當(dāng)然就上升了。
Node.js不為每個(gè)客戶連接創(chuàng)建一個(gè)新的線程,而僅僅使用一個(gè)線程。當(dāng)有用戶連接了,就觸發(fā)一個(gè)內(nèi)部事件,通過(guò)非阻塞I/O、事件驅(qū)動(dòng)機(jī)制,讓Node.js程序宏觀上也是并行的。使用Node.js,一個(gè)8GB內(nèi)存的服務(wù)器,可以同時(shí)處理超過(guò)4萬(wàn)用戶的連接。
另外,單線程的好處還有操作系統(tǒng)完全不再有線程創(chuàng)建、銷毀的時(shí)間開銷。
壞處,就是一個(gè)用戶造成了線程的崩潰,整個(gè)服務(wù)都崩潰了,其他人也崩潰了。
如以下圖:?jiǎn)尉程就像是公路上的單行線,來(lái)來(lái)往往的車輛不停的走,不浪費(fèi)資源,并且一輛一輛的通告。但是如果一旦有一輛車出現(xiàn)事故,就會(huì)影響整個(gè)線程。而多線程就像是多車道,有一條線出了問(wèn)題還可以從其它路線中通行。
單線程:
多線程:
單線程問(wèn)題:
多線程問(wèn)題:
2.非阻塞I/O
I/O操作指的是對(duì)磁盤的讀寫操作。傳統(tǒng)的服務(wù)器語(yǔ)言大多是多線程、阻塞式 I/O。這也是 Node 與眾不同的地方,對(duì)于傳統(tǒng)的服務(wù)器語(yǔ)言,在與用戶建立連接時(shí),每一個(gè)連接都是一個(gè)線程。 當(dāng)有十萬(wàn)個(gè)用戶連接時(shí),服務(wù)器上就會(huì)有十萬(wàn)個(gè)線程。而阻塞式 I/O 是指,當(dāng)一個(gè)線程在執(zhí)行 I/O 操作時(shí),這個(gè)線程會(huì)阻塞,等待 I/O 操作完成后繼續(xù)執(zhí)行。
例如,當(dāng)在訪問(wèn)數(shù)據(jù)庫(kù)取得數(shù)據(jù)的時(shí)候,需要一段時(shí)間。在傳統(tǒng)的單線程處理機(jī)制中,在執(zhí)行了訪問(wèn)數(shù)據(jù)庫(kù)代碼之后,整個(gè)線程都將暫停下來(lái),等待數(shù)據(jù)庫(kù)返回結(jié)果,才能執(zhí)行后面的代碼。也就是說(shuō),I/O阻塞了代碼的執(zhí)行,極大地降低了程序的執(zhí)行效率。
阻塞模式下,一個(gè)線程只能處理一項(xiàng)任務(wù),要想提高吞吐量必須通過(guò)多線程。而非阻塞模式下,一個(gè)線程永遠(yuǎn)在執(zhí)行計(jì)算操作,這個(gè)線程的CPU核心利用率永遠(yuǎn)是100%。所以,這是一種特別有哲理的解決方案:與其人多,但是好多人閑著;還不如一個(gè)人玩命,往死里干活兒。
3.事件驅(qū)動(dòng)
在Node.js中,客戶端請(qǐng)求建立連接,提交數(shù)據(jù)等行為,會(huì)觸發(fā)相應(yīng)的事件。在Node.js中,在一個(gè)時(shí)刻,只能執(zhí)行一個(gè)事件回調(diào)函數(shù),但是在執(zhí)行一個(gè)事件回調(diào)函數(shù)時(shí),可以轉(zhuǎn)而處理其他事件(比如,又有新用戶連接了),然后返回繼續(xù)執(zhí)行原事件的回調(diào)函數(shù),這種處理機(jī)制,稱為“事件環(huán)”機(jī)制。
Node.js底層是C++(V8也是C++寫的)。底層代碼中,近半數(shù)都用于事件隊(duì)列、回調(diào)函數(shù)隊(duì)列的構(gòu)建。用事件驅(qū)動(dòng)來(lái)完成服務(wù)器的任務(wù)調(diào)度。用一個(gè)線程,擔(dān)負(fù)起了處理非常多的任務(wù)的使命。
單線程,單線程的好處,減少了內(nèi)存開銷,如果某一個(gè)事情,進(jìn)入了,但是被I/O阻塞了,所以這個(gè)線程就阻塞了。非阻塞I/O, 不會(huì)等I/O語(yǔ)句結(jié)束,而會(huì)執(zhí)行后面的語(yǔ)句。
非阻塞就能解決問(wèn)題了么?比如執(zhí)行著A的業(yè)務(wù),執(zhí)行過(guò)程中,B的I/O回調(diào)完成了,此時(shí)怎么辦?
事件機(jī)制,事件環(huán),不管是新用戶的請(qǐng)求,還是老用戶的I/O完成,都將以事件方式加入事件環(huán),等待調(diào)度。
Node可以做什么
正是因?yàn)镹ode的3個(gè)特點(diǎn),node非常適合做任務(wù)調(diào)度而不擅長(zhǎng)做大量的邏輯運(yùn)算,因?yàn)榇罅康倪\(yùn)算又會(huì)造成嚴(yán)重的阻塞。
比如:
● Web服務(wù)API,比如REST
● 后端的Web服務(wù),例如跨域、服務(wù)器端的請(qǐng)求
● 基于Web的應(yīng)用
● 多客戶端的通信,如即時(shí)通信
Node的模塊化思想
模塊化是指解決一個(gè)復(fù)雜問(wèn)題時(shí)自頂向下逐層把系統(tǒng)劃分成若干模塊的過(guò)程,有多種屬性,分別反映其內(nèi)部特性。是一種處理復(fù)雜系統(tǒng)分解為更好的可管理模塊的方式。
在前端中且主要是JavaScript的使用情況下。存在兩大問(wèn)題,文件依賴和命名沖突。
所以在使用JavaScript的時(shí)候,要迫切擺脫這樣的問(wèn)題。在Node中提供了非常好用的Commonjs規(guī)范,具體實(shí)現(xiàn)在module.exports/exports、require上。我們?cè)陂_發(fā)中,讓一個(gè)js就是一個(gè)模塊,多個(gè)模塊可以組成完整應(yīng)用,抽離一個(gè)模塊不會(huì)影響其他功能的運(yùn)行。在主文件中只需運(yùn)行一個(gè)文件即可,其它文件依賴誰(shuí)讓它們自己管理。
總的來(lái)說(shuō):模塊化是開發(fā)者管理代碼的一種規(guī)范而已。
- // index.js
- var m = require( "./module.js" );
- m.foo()// 打印hello ujiuye
-
-
- // module.js
- function foo(){
- console.log('hello ujiuye')
- }
- // 導(dǎo)出foo
- exports.foo = foo;
Node安裝
Node.js的官網(wǎng)為:https://nodejs.org/en/
安裝包的下載地址:https://nodejs.org/en/download/
在LTS(Long Term Support,長(zhǎng)期支持版)的選項(xiàng)卡下,根據(jù)不同平臺(tái)系統(tǒng)選擇你需要的 Node.js 安裝包并下載:如下圖:
步驟一: 雙擊下載后的安裝包 node-v12.14.0-x64.msi,并點(diǎn)擊運(yùn)行,如下圖。
步驟二:點(diǎn)擊以上的運(yùn)行,將出現(xiàn)如下界面,點(diǎn)擊Next繼續(xù):
步驟三:勾選接受協(xié)議選項(xiàng),點(diǎn)擊 Next(下一步) 按鈕 :
步驟四:Node.js默認(rèn)安裝目錄為 "C:\Program Files\nodejs" , 你可以修改目錄,并點(diǎn)擊 next(下一步):
步驟五: 默認(rèn)Node.js的安裝模式 , 直接點(diǎn)Next(下一步)
這里共有4項(xiàng)安裝內(nèi)容:
1.安裝Node核心模塊
2.安裝npm
3.安裝文檔
4.把Node.js和npm及其模塊添加到環(huán)境變量
這里可以看到1和2就是Node核心程序和npm,安裝Node的時(shí)候,默認(rèn)會(huì)把Node和npm都安裝上了。 另外4是把Node和npm添加到環(huán)境變量,如果不選,之后在cmd窗口想運(yùn)行node、npm等執(zhí)行程序會(huì)報(bào)錯(cuò),系統(tǒng)找不到指定文件,當(dāng)然也可以再手動(dòng)配置系統(tǒng)環(huán)境變量。
這里建議全選,也就是默認(rèn)選項(xiàng),直接 Next
步驟六:點(diǎn)擊next,然后繼續(xù)安裝。
步驟七:點(diǎn)擊Install開始安裝。
安裝過(guò)程:
步驟八:結(jié)束安裝Node.js:
在cmd中,輸入命令node -v,檢查Node.js的版本號(hào)。
使用Node定義Http服務(wù)
安裝node.js環(huán)境 ,然后建立app.js文件,編寫如下代碼,在終端輸入 node app.js命令?梢钥吹浇K端中輸出 3000端口開啟。
那么就可以輕松搭建一個(gè)非常簡(jiǎn)單的服務(wù)器啦。然后在瀏覽器訪問(wèn) http://localhost:3000 就可以訪問(wèn)到 hello ujiuye。
- //1. 引入核心模塊http
- const http = require('http');
-
- //2. 創(chuàng)建服務(wù)器 http.createServer
- let server = http.createServer( (request,response)=>{//request|req 請(qǐng)求對(duì)象 , response|res響應(yīng)對(duì)象
- response.end('hello ujiuye')
- } )
-
-
- //console.log( server.listen )
- server.listen( 3000 ,()=>{ //端口開啟成功,則執(zhí)行此回調(diào)
- console.log('3000端口開啟');
- });