NodeJS-技術(shù)講解-課件_第1頁
NodeJS-技術(shù)講解-課件_第2頁
NodeJS-技術(shù)講解-課件_第3頁
NodeJS-技術(shù)講解-課件_第4頁
NodeJS-技術(shù)講解-課件_第5頁
已閱讀5頁,還剩151頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

Node.js1PPT課件Node.js1PPT課件Node.js簡介簡單的說Node.js就是運行在服務(wù)端的JavaScript。Node.js是一個基于ChromeJavaScript運行時建立的一個平臺。Node.js是一個事件驅(qū)動I/O服務(wù)端JavaScript環(huán)境(由C++編寫),基于Google的V8引擎,V8引擎執(zhí)行Javascript的速度非???,性能非常好。2PPT課件Node.js簡介簡單的說Node.js就是運行在服務(wù)端

Node.js的工作原理用戶Request用戶Request用戶RequestNode.js進程3PPT課件Node.js的工作原理用戶Request用戶RequesPhp模型

用戶Request用戶Request用戶RequestAPACHEPHP線程PHP線程PHP線程處理Request處理Request處理Request4PPT課件Php模型用戶Request用戶Request用戶RequeNodeJS優(yōu)缺點及適用場景討論NodeJS的特點NodeJS帶來的對系統(tǒng)瓶頸的解決方案NodeJS的優(yōu)缺點適合NodeJS的場景5PPT課件NodeJS優(yōu)缺點及適用場景討論NodeJS的特點5PPT課NodeJS的特點1.它是一個Javascript運行環(huán)境(C++實現(xiàn))2.依賴于ChromeV8引擎進行代碼解釋3.事件驅(qū)動4.非阻塞I/O5.輕量、可伸縮,適于實時數(shù)據(jù)交互應(yīng)用6.單進程,單線程7.模塊化編程8.事件輪詢(eventloop)6PPT課件NodeJS的特點1.它是一個Javascript運行環(huán)境NodeJS帶來的對系統(tǒng)瓶頸的解決方案它的出現(xiàn)確實能為我們解決現(xiàn)實當(dāng)中系統(tǒng)瓶頸提供了新的思路和方案,下面我們看看它能解決什么問題。1.并發(fā)連接舉個例子,想象一個場景,我們在銀行排隊辦理業(yè)務(wù),我們看看下面兩個模型。7PPT課件NodeJS帶來的對系統(tǒng)瓶頸的解決方案它的出現(xiàn)確實能為我們解(1)系統(tǒng)線程模型:這種模型的問題顯而易見,服務(wù)端只有一個線程,并發(fā)請求(用戶)到達只能處理一個,其余的要先等待,這就是阻塞,正在享受服務(wù)的請求阻塞后面的請求了。8PPT課件這種模型的問題顯而易見,服務(wù)端只有一個線程,并發(fā)請求(用戶)(2)多線程、線程池模型:這個模型已經(jīng)比上一個有所進步,它調(diào)節(jié)服務(wù)端線程的數(shù)量來提高對并發(fā)請求的接收和響應(yīng),但并發(fā)量高的時候,請求仍然需要等待,它有個更嚴重的問題。到代碼層面上來講,我們看看客戶端請求與服務(wù)端通訊的過程:9PPT課件(2)多線程、線程池模型:這個模型已經(jīng)比上一個有所進步,它調(diào)服務(wù)端與客戶端每建立一個連接,都要為這個連接分配一套配套的資源,主要體現(xiàn)為系統(tǒng)內(nèi)存資源,以PHP為例,維護一個連接可能需要20M的內(nèi)存。這就是為什么一般并發(fā)量一大,就需要多開服務(wù)器。那么NodeJS是怎么解決這個問題的呢?我們來看另外一個模型,想象一下我們在快餐店點餐吃飯的場景。10PPT課件服務(wù)端與客戶端每建立一個連接,都要為這個連接分配一套配套的資(3)異步、事件驅(qū)動模型我們同樣是要發(fā)起請求,等待服務(wù)器端響應(yīng);但是與銀行例子不同的是,這次我們點完餐后拿到了一個號碼,拿到號碼,我們往往會在位置上等待,而在我們后面的請求會繼續(xù)得到處理,同樣是拿了一個號碼然后到一旁等待,接待員能一直進行處理。等到飯菜做號了,會喊號碼,我們拿到了自己的飯菜,進行后續(xù)的處理(吃飯)。這個喊號碼的動作在NodeJS中叫做回調(diào)(Callback),能在事件(燒菜,I/O)處理完成后繼續(xù)執(zhí)行后面的邏輯(吃飯),這體現(xiàn)了NodeJS的顯著特點,異步機制、事件驅(qū)動整個過程沒有阻塞新用戶的連接(點餐),也不需要維護已經(jīng)點餐的用戶與廚師的連接。11PPT課件(3)異步、事件驅(qū)動模型我們同樣是要發(fā)起請求,等待服務(wù)器端響基于這樣的機制,理論上陸續(xù)有用戶請求連接,NodeJS都可以進行響應(yīng),因此NodeJS能支持比Java、PHP程序更高的并發(fā)量雖然維護事件隊列也需要成本,再由于NodeJS是單線程,事件隊列越長,得到響應(yīng)的時間就越長,并發(fā)量上去還是會力不從心??偨Y(jié)一下NodeJS是怎么解決并發(fā)連接這個問題的:更改連接到服務(wù)器的方式,每個連接發(fā)射(emit)一個在NodeJS引擎進程中運行的事件(Event),放進事件隊列當(dāng)中,而不是為每個連接生成一個新的OS線程(并為其分配一些配套內(nèi)存)。12PPT課件基于這樣的機制,理論上陸續(xù)有用戶請求連接,NodeJS都可以2.I/O阻塞NodeJS解決的另外一個問題是I/O阻塞,看看這樣的業(yè)務(wù)場景:需要從多個數(shù)據(jù)源拉取數(shù)據(jù),然后進行處理。(1)串行獲取數(shù)據(jù),這是我們一般的解決方案,以PHP為例假如獲取profile和timeline操作各需要1S,那么串行獲取就需要2S。13PPT課件2.I/O阻塞13PPT課件(2)NodeJS非阻塞I/O,發(fā)射/監(jiān)聽事件來控制執(zhí)行過程NodeJS遇到I/O事件會創(chuàng)建一個線程去執(zhí)行,然后主線程會繼續(xù)往下執(zhí)行的,因此,拿profile的動作觸發(fā)一個I/O事件,馬上就會執(zhí)行拿timeline的動作,兩個動作并行執(zhí)行,假如各需要1S,那么總的時間也就是1S。它們的I/O操作執(zhí)行完成后,發(fā)射一個事件,profile和timeline,事件代理接收后繼續(xù)往下執(zhí)行后面的邏輯,這就是NodeJS非阻塞I/O的特點。14PPT課件(2)NodeJS非阻塞I/O,發(fā)射/監(jiān)聽事件來控制執(zhí)行過程總結(jié)一下:Java、PHP也有辦法實現(xiàn)并行請求(子線程),但NodeJS通過回調(diào)函數(shù)(Callback)和異步機制會做得很自然。三.NodeJS的優(yōu)缺點優(yōu)點:1.高并發(fā)(最重要的優(yōu)點,據(jù)說可以應(yīng)付百萬級并發(fā))2.適合I/O密集型應(yīng)用缺點:1.不適合CPU密集型應(yīng)用;CPU密集型應(yīng)用給Node帶來的挑戰(zhàn)主要是:由于JavaScript單線程的原因,如果有長時間運行的計算(比如大循環(huán)),將會導(dǎo)致CPU時間片不能釋放,使得后續(xù)I/O無法發(fā)起;解決方案:分解大型運算任務(wù)為多個小任務(wù),使得運算能夠適時釋放,不阻塞I/O調(diào)用的發(fā)起;2.只支持單核CPU,不能充分利用CPU3.可靠性低,一旦代碼某個環(huán)節(jié)崩潰,整個系統(tǒng)都崩潰原因:單進程,單線程解決方案:(1)Nnigx反向代理,負載均衡,開多個進程,綁定多個端口;(2)開多個進程監(jiān)聽同一個端口,使用cluster模塊;4.開源組件庫質(zhì)量參差不齊,更新快,向下不兼容5.Debug不方便,錯誤沒有stacktrace15PPT課件總結(jié)一下:Java、PHP也有辦法實現(xiàn)并行請求(子線程),但四.適合NodeJS的場景1.RESTfulAPI這是NodeJS最理想的應(yīng)用場景,可以處理數(shù)萬條連接,本身沒有太多的邏輯,只需要請求API,組織數(shù)據(jù)進行返回即可。它本質(zhì)上只是從某個數(shù)據(jù)庫中查找一些值并將它們組成一個響應(yīng)。由于響應(yīng)是少量文本,入站請求也是少量的文本,因此流量不高,一臺機器甚至也可以處理最繁忙的公司的API需求。2.統(tǒng)一Web應(yīng)用的UI層目前MVC的架構(gòu),在某種意義上來說,Web開發(fā)有兩個UI層,一個是在瀏覽器里面我們最終看到的,另一個在server端,負責(zé)生成和拼接頁面。不討論這種架構(gòu)是好是壞,但是有另外一種實踐,面向服務(wù)的架構(gòu),更好的做前后端的依賴分離。如果所有的關(guān)鍵業(yè)務(wù)邏輯都封裝成REST調(diào)用,就意味著在上層只需要考慮如何用這些REST接口構(gòu)建具體的應(yīng)用。那些后端程序員們根本不操心具體數(shù)據(jù)是如何從一個頁面?zhèn)鬟f到另一個頁面的,他們也不用管用戶數(shù)據(jù)更新是通過Ajax異步獲取的還是通過刷新頁面。3.大量Ajax請求的應(yīng)用例如個性化應(yīng)用,每個用戶看到的頁面都不一樣,緩存失效,需要在頁面加載的時候發(fā)起Ajax請求,NodeJS能響應(yīng)大量的并發(fā)請求??偠灾?,NodeJS適合運用在高并發(fā)、I/O密集、少量業(yè)務(wù)邏輯的場景。16PPT課件四.適合NodeJS的場景16PPT課件花瓣網(wǎng)淘寶開放平臺API調(diào)用Nodejs版本實現(xiàn)C社區(qū)成功案例網(wǎng)易開源基于Node.js的游戲服務(wù)器框架pomeloNodeOS(NodeOS是采用NodeJS開發(fā)的一款友好的操作系統(tǒng))17PPT課件花瓣網(wǎng)淘寶開放平臺API調(diào)用Nodejs版本實現(xiàn)Cnode.EventLoop18PPT課件EventLoop18PPT課件什么是EventLoop?EventLoop是一個很重要的概念,指的是計算機系統(tǒng)的一種運行機制。JavaScript語言就采用這種機制,來解決單線程運行帶來的一些問題。本文參考C.AaronCois的《UnderstandingTheNode.jsEventLoop》,解釋什么是EventLoop,以及它與JavaScript語言的單線程模型有何關(guān)系。19PPT課件什么是EventLoop?本文參考C.AaronCo想要理解EventLoop,就要從程序的運行模式講起。運行以后的程序叫做"進程"(process),一般情況下,一個進程一次只能執(zhí)行一個任務(wù)。如果有很多任務(wù)需要執(zhí)行,不外乎三種解決方法。以JavaScript語言為例,它是一種單線程語言,所有任務(wù)都在一個線程上完成,即采用上面的第一種方法。一旦遇到大量任務(wù)或者遇到一個耗時的任務(wù),網(wǎng)頁就會出現(xiàn)"假死",因為JavaScript停不下來,也就無法響應(yīng)用戶的行為。你也許會問,JavaScript為什么是單線程,難道不能實現(xiàn)為多線程嗎?這跟歷史有關(guān)系。JavaScript從誕生起就是單線程。原因大概是不想讓瀏覽器變得太復(fù)雜,因為多線程需要共享資源、且有可能修改彼此的運行結(jié)果,對于一種網(wǎng)頁腳本語言來說,這就太復(fù)雜了。后來就約定俗成,JavaScript為一種單線程語言。(WorkerAPI可以實現(xiàn)多線程,但是JavaScript本身始終是單線程的。)20PPT課件想要理解EventLoop,就要從程序的運行模式講起。運行如果某個任務(wù)很耗時,比如涉及很多I/O(輸入/輸出)操作,那么線程的運行大概是下面的樣子。上圖的綠色部分是程序的運行時間,紅色部分是等待時間??梢钥吹?,由于I/O操作很慢,所以這個線程的大部分運行時間都在空等I/O操作的返回結(jié)果。這種運行方式稱為"同步模式"(synchronousI/O)或"堵塞模式"(blockingI/O)。21PPT課件如果某個任務(wù)很耗時,比如涉及很多I/O(輸入/輸出)操作,那如果采用多線程,同時運行多個任務(wù),那很可能就是下面這樣。上圖表明,多線程不僅占用多倍的系統(tǒng)資源,也閑置多倍的資源,這顯然不合理。EventLoop就是為了解決這個問題而提出的。Wikipedia這樣定義:22PPT課件如果采用多線程,同時運行多個任務(wù),那很可能就是下面這樣。上圖EventLoop是一個程序結(jié)構(gòu),用于等待和發(fā)送消息和事件。簡單說,就是在程序中設(shè)置兩個線程:一個負責(zé)程序本身的運行,稱為"主線程";另一個負責(zé)主線程與其他進程(主要是各種I/O操作)的通信,被稱為"EventLoop線程"(可以譯為"消息線程")。23PPT課件EventLoop是一個程序結(jié)構(gòu),用于等待和發(fā)送消息和事件上圖主線程的綠色部分,還是表示運行時間,而橙色部分表示空閑時間。每當(dāng)遇到I/O的時候,主線程就讓EventLoop線程去通知相應(yīng)的I/O程序,然后接著往后運行,所以不存在紅色的等待時間。等到I/O程序完成操作,EventLoop線程再把結(jié)果返回主線程。主線程就調(diào)用事先設(shè)定的回調(diào)函數(shù),完成整個任務(wù)??梢钥吹剑捎诙喑隽顺壬目臻e時間,所以主線程得以運行更多的任務(wù),這就提高了效率。這種運行方式稱為"異步模式"(asynchronousI/O)或"非堵塞模式"(non-blockingmode)。這正是JavaScript語言的運行方式。單線程模型雖然對JavaScript構(gòu)成了很大的限制,但也因此使它具備了其他語言不具備的優(yōu)勢。如果部署得好,JavaScript程序是不會出現(xiàn)堵塞的,這就是為什么node.js平臺可以用很少的資源,應(yīng)付大流量訪問的原因。24PPT課件上圖主線程的綠色部分,還是表示運行時間,而橙色部分表示空閑時Node.js

語法25PPT課件Node.js

語法25PPT課件第一個Node.js程序:HelloWorld!以下是我們的第一個Node.js程序:console.log("HelloWorld");保存該文件,并通過Node.js來執(zhí)行:nodehelloworld.js程序執(zhí)行后,正常的話,就會在終端輸出HelloWorld。26PPT課件第一個Node.js程序:HelloWorld!26PPTNode.js安裝配置window和Linux上安裝Node.js的方法Node.js安裝包及源碼下載地址為:/download/。根據(jù)不同平臺系統(tǒng)選擇你需要的Node.js安裝包。注意:Linux上安裝Node.js需要安裝Python2.6或2.7,不建議安裝Python3.0以上版本。27PPT課件Node.js安裝配置根據(jù)不同平臺系統(tǒng)選擇你需要的NodeWindowv上安裝Node.jsWindows安裝包(.msi):32位安裝包下載地址:/dist/v0.10.26/node-v0.10.26-x86.msi64位安裝包下載地址:/dist/v0.10.26/x64/node-v0.10.26-x64.msi安裝步驟:步驟1:雙擊下載后的安裝包node-v0.10.26-x86.msi,如下所示:28PPT課件Windowv上安裝Node.js28PPT課件安裝過程省略。。console.log("HelloWorld");保存該文件,并通過Node.js來執(zhí)行:nodehelloworld.js程序執(zhí)行后,正常的話,就會在終端輸出HelloWorld。29PPT課件安裝過程省略。。console.log("HelloWorNode.js創(chuàng)建HTTP服務(wù)器如果我們使用PHP來編寫后端的代碼時,需要Apache或者Nginx的HTTP服務(wù)器,并配上mod_php5模塊和php-cgi。從這個角度看,整個"接收HTTP請求并提供Web頁面"的需求根本不需要PHP來處理。不過對Node.js來說,概念完全不一樣了。使用Node.js時,我們不僅僅在實現(xiàn)一個應(yīng)用,同時還實現(xiàn)了整個HTTP服務(wù)器。事實上,我們的Web應(yīng)用以及對應(yīng)的Web服務(wù)器基本上是一樣的?;A(chǔ)的HTTP服務(wù)器在你的項目的根目錄下創(chuàng)建一個叫server.js的文件,并寫入以下代碼:30PPT課件Node.js創(chuàng)建HTTP服務(wù)器如果我們使用PHP來編寫后以上代碼我們完成了一個可以工作的HTTP服務(wù)器。使用node命令執(zhí)行以上的代碼:接下來,打開瀏覽器訪問:8888/,你會看到一個寫著"HelloWorld"的網(wǎng)頁。31PPT課件以上代碼我們完成了一個可以工作的HTTP服務(wù)器。接下來,分析Node.js的HTTP服務(wù)器:第一行請求(require)Node.js自帶的http模塊,并且把它賦值給http變量。接下來我們調(diào)用http模塊提供的函數(shù):createServer。這個函數(shù)會返回一個對象,這個對象有一個叫做listen的方法,這個方法有一個數(shù)值參數(shù),指定這個HTTP服務(wù)器監(jiān)聽的端口號。32PPT課件分析Node.js的HTTP服務(wù)器:32PPT課件Node.js模塊系統(tǒng)為了讓Node.js的文件可以相互調(diào)用,Node.js提供了一個簡單的模塊系統(tǒng)。模塊是Node.js應(yīng)用程序的基本組成部分,文件和模塊是一一對應(yīng)的。換言之,一個Node.js文件就是一個模塊,這個文件可能是JavaScript代碼、JSON或者編譯過的C/C++擴展。創(chuàng)建模塊在Node.js中,創(chuàng)建一個模塊非常簡單,如下我們創(chuàng)建一個'main.js'文件,代碼如下:以上實例中,代碼require('./hello')引入了當(dāng)前目錄下的hello.js文件(./為當(dāng)前目錄,node.js默認后綴為js)。Node.js提供了exports和require兩個對象,其中exports是模塊公開的接口,require用于從外部獲取一個模塊的接口,即所獲取模塊的exports對象。接下來我們就來創(chuàng)建hello.js文件,代碼如下:33PPT課件Node.js模塊系統(tǒng)創(chuàng)建模塊以上實例中,代碼requir在以上示例中,hello.js通過exports對象把world作為模塊的訪問接口,在main.js中通過require('./hello')加載這個模塊,然后就可以直接訪問main.js中exports對象的成員函數(shù)了。34PPT課件在以上示例中,hello.js通過exports對象把35PPT課件35PPT課件Node.js事件Node.js所有的異步I/O操作在完成時都會發(fā)送一個事件到事件隊列。Node.js里面的許多對象都會分發(fā)事件:一個net.Server對象會在每次有新連接時分發(fā)一個事件,一個fs.readStream對象會在文件被打開的時候發(fā)出一個事件。所有這些產(chǎn)生事件的對象都是events.EventEmitter的實例。你可以通過require("events");來訪問該模塊。下面我們用一個簡單的例子說明EventEmitter的用法:運行這段代碼,1秒后控制臺輸出了'some_eventoccured'。其原理是event對象注冊了事件some_event的一個監(jiān)聽器,然后我們通過setTimeout在1000毫秒以后向event對象發(fā)送事件some_event,此時會調(diào)用some_event的監(jiān)聽器。36PPT課件Node.js事件運行這段代碼,1秒后控制臺輸出了'soNode.js函數(shù)在JavaScript中,一個函數(shù)可以作為另一個函數(shù)接收一個參數(shù)。我們可以先定義一個函數(shù),然后傳遞,也可以在傳遞參數(shù)的地方直接定義函數(shù)。Node.js中函數(shù)的使用與Javascript類似,舉例來說,你可以這樣做:以上代碼中,我們把say函數(shù)作為execute函數(shù)的第一個變量進行了傳遞。這里返回的不是say的返回值,而是say本身!這樣一來,say就變成了execute中的本地變量someFunction,execute可以通過調(diào)用someFunction()(帶括號的形式)來使用say函數(shù)。當(dāng)然,因為say有一個變量,execute在調(diào)用someFunction時可以傳遞這樣一個變量。37PPT課件Node.js函數(shù)以上代碼中,我們把say函數(shù)作為ex匿名函數(shù)我們可以把一個函數(shù)作為變量傳遞。但是我們不一定要繞這個"先定義,再傳遞"的圈子,我們可以直接在另一個函數(shù)的括號中定義和傳遞這個函數(shù):我們在execute接受第一個參數(shù)的地方直接定義了我們準備傳遞給execute的函數(shù)。用這種方式,我們甚至不用給這個函數(shù)起名字,這也是為什么它被叫做匿名函數(shù)。38PPT課件匿名函數(shù)我們在execute接受第一個參數(shù)的地方直接定義函數(shù)傳遞是如何讓HTTP服務(wù)器工作的帶著這些知識,我們再來看看我們簡約而不簡單的HTTP服務(wù)器:現(xiàn)在它看上去應(yīng)該清晰了很多:我們向createServer函數(shù)傳遞了一個匿名函數(shù)。用這樣的代碼也可以達到同樣的目的:39PPT課件函數(shù)傳遞是如何讓HTTP服務(wù)器工作的現(xiàn)在它看上去應(yīng)該清晰了很Node.js路由我們要為路由提供請求的URL和其他需要的GET及POST參數(shù),隨后路由需要根據(jù)這些數(shù)據(jù)來執(zhí)行相應(yīng)的代碼。因此,我們需要查看HTTP請求,從中提取出請求的URL以及GET/POST參數(shù)。這一功能應(yīng)當(dāng)屬于路由還是服務(wù)器(甚至作為一個模塊自身的功能)確實值得探討,但這里暫定其為我們的HTTP服務(wù)器的功能。我們需要的所有數(shù)據(jù)都會包含在request對象中,該對象作為onRequest()回調(diào)函數(shù)的第一個參數(shù)傳遞。但是為了解析這些數(shù)據(jù),我們需要額外的Node.JS模塊,它們分別是url和querystring模塊。40PPT課件Node.js路由40PPT課件當(dāng)然我們也可以用querystring模塊來解析POST請求體中的參數(shù),稍后會有演示?,F(xiàn)在我們來給onRequest()函數(shù)加上一些邏輯,用來找出瀏覽器請求的URL路徑:好了,我們的應(yīng)用現(xiàn)在可以通過請求的URL路徑來區(qū)別不同請求了--這使我們得以使用路由(還未完成)來將請求以URL路徑為基準映射到處理程序上。41PPT課件當(dāng)然我們也可以用querystring模塊來解析POST請求Node.js全局對象JavaScript中有一個特殊的對象,稱為全局對象(GlobalObject),它及其所有屬性都可以在程序的任何地方訪問,即全局變量。在瀏覽器JavaScript中,通常window是全局對象,而Node.js中的全局對象是global,所有全局變量(除了global本身以外)都是global對象的屬性。我們在Node.js中能夠直接訪問到對象通常都是global的屬性,如console、process等,下面逐一介紹。全局對象與全局變量global最根本的作用是作為全局變量的宿主。按照ECMAScript的定義,滿足以下條件的變量是全局變量:在最外層定義的變量;全局對象的屬性;隱式定義的變量(未定義直接賦值的變量)。當(dāng)你定義一個全局變量時,這個變量同時也會成為全局對象的屬性,反之亦然。需要注意的是,在Node.js中你不可能在最外層定義變量,因為所有用戶代碼都是屬于當(dāng)前模塊的,而模塊本身不是最外層上下文。注意:

永遠使用var定義變量以避免引入全局變量,因為全局變量會污染命名空間,提高代碼的耦合風(fēng)險。42PPT課件Node.js全局對象全局對象與全局變量42PPT課件processprocess是一個全局變量,即global對象的屬性。它用于描述當(dāng)前Node.js進程狀態(tài)的對象,提供了一個與操作系統(tǒng)的簡單接口。通常在你寫本地命令行程序的時候,少不了要和它打交道。下面將會介紹process對象的一些最常用的成員方法。process.argv是命令行參數(shù)數(shù)組,第一個元素是node,第二個元素是腳本文件名,從第三個元素開始每個元素是一個運行參數(shù)。將以上代碼存儲為argv.js,通過以下命令運行:43PPT課件process將以上代碼存儲為argv.js,通過以下命令運process.stdout是標準輸出流,通常我們使用的console.log()向標準輸出打印字符,而process.stdout.write()函數(shù)提供了更底層的接口。process.stdin是標準輸入流,初始時它是被暫停的,要想從標準輸入讀取數(shù)據(jù),你必須恢復(fù)流,并手動編寫流的事件響應(yīng)函數(shù)。process.nextTick(callback)的功能是為事件循環(huán)設(shè)置一項任務(wù),Node.js會在下次事件循環(huán)調(diào)響應(yīng)時調(diào)用callback。consoleconsole用于提供控制臺標準輸出,它是由InternetExplorer的JScript引擎提供的調(diào)試工具,后來逐漸成為瀏覽器的事實標準。Node.js沿用了這個標準,提供與習(xí)慣行為一致的console對象,用于向標準輸出流(stdout)或標準錯誤流(stderr)輸出字符。console.log():向標準輸出流打印字符并以換行符結(jié)束。console.log接受若干個參數(shù),如果只有一個參數(shù),則輸出這個參數(shù)的字符串形式。如果有多個參數(shù),則以類似于C語言printf()命令的格式輸出。第一個參數(shù)是一個字符串,如果沒有參數(shù),只打印一個換行。44PPT課件process.stdout是標準輸出流,通常我們使用的c運行結(jié)果為:45PPT課件運行結(jié)果為:45PPT課件Node.js常用工具utilutil是一個Node.js核心模塊,提供常用函數(shù)的集合,用于彌補核心JavaScript的功能過于精簡的不足。util.inheritsutil.inherits(constructor,superConstructor)是一個實現(xiàn)對象間原型繼承的函數(shù)。JavaScript的面向?qū)ο筇匦允腔谠偷模c常見的基于類的不同。JavaScript沒有提供對象繼承的語言級別特性,而是通過原型復(fù)制來實現(xiàn)的。til.inspectutil.inspect(object,[showHidden],[depth],[colors])是一個將任意對象轉(zhuǎn)換為字符串的方法,通常用于調(diào)試和錯誤輸出。它至少接受一個參數(shù)object,即要轉(zhuǎn)換的對象。util.isArray(object)如果給定的參數(shù)"object"是一個數(shù)組返回true,否則返回false。util.isRegExp(object)如果給定的參數(shù)"object"是一個正則表達式返回true,否則返回false。util.isDate(object)如果給定的參數(shù)"object"是一個日期返回true,否則返回false。util.isError(object)如果給定的參數(shù)"object"是一個錯誤對象返回true,否則返回false。46PPT課件Node.js常用工具utilutil.inheritsNode.js文件系統(tǒng)Node.js文件系統(tǒng)封裝在fs模塊是中,它提供了文件的讀取、寫入、更名、刪除、遍歷目錄、鏈接等POSIX文件系統(tǒng)操作。與其他模塊不同的是,fs模塊中所有的操作都提供了異步的和同步的兩個版本,例如讀取文件內(nèi)容的函數(shù)有異步的fs.readFile()和同步的fs.readFileSync()。我們以幾個函數(shù)為代表,介紹fs常用的功能,并列出fs所有函數(shù)的定義和功能。fs.readFileNode.js讀取文件函數(shù)語法如下:如果不指定encoding,則callback就是第二個參數(shù)。回調(diào)函數(shù)提供兩個參數(shù)err和data,err表示有沒有錯誤發(fā)生,data是文件內(nèi)容。如果指定了encoding,data是一個解析后的字符串,否則data將會是以Buffer形式表示的二進制數(shù)據(jù)。例如以下程序,我們從content.txt中讀取數(shù)據(jù),但不指定編碼:47PPT課件Node.js文件系統(tǒng)fs.readFile如果不指定假設(shè)content.txt中的內(nèi)容是UTF-8編碼的Text文本文件示例,運行結(jié)果如下:這個程序以二進制的模式讀取了文件的內(nèi)容,data的值是Buffer對象。如果我們給fs.readFile的encoding指定編碼:48PPT課件假設(shè)content.txt中的內(nèi)容是UTF-8編碼的T那么運行結(jié)果則是:當(dāng)讀取文件出現(xiàn)錯誤時,err將會是Error對象。如果content.txt不存在,運行前面的代碼則會出現(xiàn)以下結(jié)果:fs.readFileSyncfs.readFileSync(filename,[encoding])是fs.readFile同步的版本。它接受的參數(shù)和fs.readFile相同,而讀取到的文件內(nèi)容會以函數(shù)返回值的形式返回。如果有錯誤發(fā)生,fs將會拋出異常,你需要使用try和catch捕捉并處理異常。注意:與同步I/O函數(shù)不同,Node.js中異步函數(shù)大多沒有返回值。49PPT課件那么運行結(jié)果則是:當(dāng)讀取文件出現(xiàn)錯誤時,err將會是Erfs.openfs.open(path,flags,[mode],[callback(err,fd)])是POSIXopen函數(shù)的封裝,與C語言標準庫中的fopen函數(shù)類似。它接受兩個必選參數(shù),path為文件的路徑,flags可以是以下值。r:以讀取模式打開文件。r+:以讀寫模式打開文件。w:以寫入模式打開文件,如果文件不存在則創(chuàng)建。w+:以讀寫模式打開文件,如果文件不存在則創(chuàng)建。a:以追加模式打開文件,如果文件不存在則創(chuàng)建。a+:以讀取追加模式打開文件,如果文件不存在則創(chuàng)建fs.readfs.read語法格式如下:50PPT課件fs.openfs.read50PPT課件參數(shù)說明:fd:讀取數(shù)據(jù)并寫入buffer指向的緩沖區(qū)對象。offset:是buffer的寫入偏移量。length:是要從文件中讀取的字節(jié)數(shù)。position:是文件讀取的起始位置,如果position的值為null,則會從當(dāng)前文件指針的位置讀取。callback:回調(diào)函數(shù)傳遞bytesRead和buffer,分別表示讀取的字節(jié)數(shù)和緩沖區(qū)對象。以下是一個使用fs.open和fs.read的示例。51PPT課件參數(shù)說明:51PPT課件運行結(jié)果是:一般來說,除非必要,否則不要使用這種方式讀取文件,因為它要求你手動管理緩沖區(qū)和文件指針,尤其是在你不知道文件大小的時候,這將會是一件很麻煩的事情。fs模塊函數(shù)表52PPT課件運行結(jié)果是:一般來說,除非必要,否則不要使用這種方式讀取文件53PPT課件53PPT課件Express+MongDB多人博客Redis漂流瓶服務(wù)器Meteor微博網(wǎng)站Socket.io+Angular單頁應(yīng)用(聊天室)網(wǎng)絡(luò)爬蟲Demo54PPT課件Express+MongDB多人博客Demo54PPT課件Socket.io在線聊天室55PPT課件Socket.io在線聊天室55PPT課件依賴框架Socket.io(實現(xiàn)即時通訊,核心)Express(快速構(gòu)建HTTPweb服務(wù)器,實現(xiàn)路由,cookie,session等)Ajs(模板)Angularjs(數(shù)據(jù)雙向綁定更新,封裝DOM操作,實現(xiàn)MVC架構(gòu))mongDB(數(shù)據(jù)庫)56PPT課件依賴框架Socket.io(實現(xiàn)即時通訊,核心)56PPT課開發(fā)工具VisualStudio2012(2013)WebStorm57PPT課件開發(fā)工具VisualStudio2012(2013)57目錄socket.io介紹服務(wù)器端和客戶端通信設(shè)計服務(wù)器端實現(xiàn)客戶端實現(xiàn)58PPT課件目錄58PPT課件1.socket.io介紹socket.io一個是基于Nodejs架構(gòu)體系的,支持websocket的協(xié)議用于時時通信的一個軟件包。socket.io給跨瀏覽器構(gòu)建實時應(yīng)用提供了完整的封裝,socket.io完全由javascript實現(xiàn)。由于socket.io.js文件中會要求flashplayer版本》10.0;請確保此項要求滿足socket.io(官網(wǎng):http://socket.io/)是一個跨平臺,多種連接方式自動切換,做即時通訊方面的開發(fā)很方便,而且能和express提供的傳統(tǒng)請求方式很好的結(jié)合,即可以在同一個域名,同一個端口提供兩種連接方式:request/response,websocket(flashsocket,ajax…).Socket.IO旨在讓各種瀏覽器與移動設(shè)備上實現(xiàn)實時app功能,模糊化各種傳輸機制。2.服務(wù)器端和客戶端通信設(shè)計59PPT課件1.socket.io介紹2.服務(wù)器端和客戶端通信設(shè)計560PPT課件60PPT課件上圖中client1和server描述通信過程,client2描述對其他的客戶端,通過廣播進行消息通信。client1向server發(fā)起連接請求server接受client的連接client1輸入登陸用戶名server返回歡迎語server通過廣播告訴其他在線的用戶,client1已登陸client1發(fā)送聊天信息server返回聊天信息(可省略)server通過廣播告訴其他在線的用戶,client1的聊天消息client1關(guān)閉連接,退出登陸server通過廣播告訴其他在線的用戶,client1已退出61PPT課件上圖中client1和server描述通信過程,cli4.客戶端實現(xiàn)CLIENT(INDEX.HTML)<scriptsrc="/socket.io/socket.io.js"></script><script>varsocket=io.connect('http://localhost');socket.on('news',function(data){console.log(data);});socket.emit('myotherevent',{my:'data'});</script>客戶端(這里是瀏覽器)通過引入<scriptsrc="/socket.io/socket.io.js"></script>即可使用socket.io。varsocket=io.connect('http://localhost');與http://localhost本地服務(wù)器建立連接并賦值給socket對象,如果是與其他服務(wù)器建立連接則只需將connect()參數(shù)修改為服務(wù)器的地址即可,這里socket.io客戶端和服務(wù)器位于同一個服務(wù)器上,那么也可以簡寫為varsocket=io.connect();62PPT課件4.客戶端實現(xiàn)CLIENT(INDEX.HTML)客戶端3.服務(wù)器端實現(xiàn)SERVER(APP.JS)varapp=require('express')(),server=require('http').createServer(app),io=require('socket.io').listen(server);server.listen(80);app.get('/',function(req,res){res.sendfile(__dirname+'/index.html');});io.sockets.on('connection',function(socket){socket.emit('news',{hello:'world'});socket.on('myotherevent',function(data){console.log(data);});});63PPT課件3.服務(wù)器端實現(xiàn)SERVER(APP.JS)63PPT課其中io=require('socket.io').listen(server);將socket.io綁定到服務(wù)器上,于是任何連接到該服務(wù)器的客戶端都具備了實時通信功能。io.sockets.on('connection',function(socket){...})的作用是服務(wù)器監(jiān)聽所有客戶端,并返回該新連接對象,接下來我們就可以通過該連接對象(socket)與客戶端進行通信了。你可以看到不管是服務(wù)器還是客戶端都有emit和on這兩個函數(shù),可以說socket.io的核心就是這兩個函數(shù)了,通過emit和on可以輕松地實現(xiàn)服務(wù)器與客戶端之間的雙向通信。emit:用來發(fā)射一個事件或者說觸發(fā)一個事件,第一個參數(shù)為事件名,第二個參數(shù)為要發(fā)送的數(shù)據(jù),第三個參數(shù)為回調(diào)函數(shù)(一般省略,如需對方接受到信息后立即得到確認時,則需要用到回調(diào)函數(shù))。on:用來監(jiān)聽一個emit發(fā)射的事件,第一個參數(shù)為要監(jiān)聽的事件名,第二個參數(shù)為一個匿名函數(shù)用來接收對方發(fā)來的數(shù)據(jù),該匿名函數(shù)的第一個參數(shù)為接收的數(shù)據(jù),若有第二個參數(shù),則為要返回的函數(shù)。socket.io提供了三種默認的事件(客戶端和服務(wù)器都有):connect、message、disconnect。當(dāng)與對方建立連接后自動觸發(fā)connect事件,當(dāng)收到對方發(fā)來的數(shù)據(jù)后觸發(fā)message事件(通常為socket.send()觸發(fā)),當(dāng)對方關(guān)閉連接后觸發(fā)disconnect事件。64PPT課件其中io=require('socket.io').l此外,socket.io還支持自定義事件,畢竟以上三種事件應(yīng)用范圍有限,正是通過這些自定義的事件才實現(xiàn)了豐富多彩的通信。最后,需要注意的是,在服務(wù)器端區(qū)分以下三種情況:socket.emit():向建立該連接的客戶端廣播socket.broadcast.emit():向除去建立該連接的客戶端的所有客戶端廣播io.sockets.emit():向所有客戶端廣播,等同于上面兩個的和65PPT課件此外,socket.io還支持自定義事件,畢竟以上三種事件MongoDB66PPT課件MongoDB66PPT課件MongoDB簡介MongoDB是一個高性能,開源,無模式的文檔型數(shù)據(jù)庫,是當(dāng)前NoSql數(shù)據(jù)庫中比較熱門的一種。它在許多場景下可用于替代傳統(tǒng)的關(guān)系型數(shù)據(jù)庫或鍵/值存儲方式。Mongo使用C++開發(fā)。MongoDB是一個介于關(guān)系數(shù)據(jù)庫和非關(guān)系數(shù)據(jù)庫之間的產(chǎn)品,是非關(guān)系數(shù)據(jù)庫當(dāng)中功能最豐富,最像關(guān)系數(shù)據(jù)庫的。他支持的數(shù)據(jù)結(jié)構(gòu)非常松散,是類似json的bson格式,因此可以存儲比較復(fù)雜的數(shù)據(jù)類型。Mongo最大的特點是他支持的查詢語言非常強大,其語法有點類似于面向?qū)ο蟮牟樵冋Z言,幾乎可以實現(xiàn)類似關(guān)系數(shù)據(jù)庫單表查詢的絕大部分功能,而且還支持對數(shù)據(jù)建立索引。

67PPT課件MongoDB簡介MongoDB是一個高性能,開源,無模式的MongoDB簡介1.數(shù)據(jù)結(jié)構(gòu)MongoDB使用文檔型存儲,其數(shù)據(jù)結(jié)構(gòu)為與JSON類似的BSON結(jié)構(gòu),而Cassandra支持的是key-value式存儲,而每個key-value還會保存一個時間戳,這個時間戳實際上起到了版本控制的作用。2.索引結(jié)構(gòu)MongoDB的索引幾乎與關(guān)系型數(shù)據(jù)庫完全一樣,其普通索引、聯(lián)合索引、唯一索引的意義和實現(xiàn)上都可以參考對MySQL索引的理解。而Cassandra由于其是一個key-value結(jié)構(gòu)的存儲,如果你要對value進行條件查找,那么就必須建立反向索引,重新建立一個value-key的鍵值對。Mongo主要解決的是海量數(shù)據(jù)的訪問效率問題,根據(jù)官方的文檔,當(dāng)數(shù)據(jù)量達到50GB以上的時候,Mongo的數(shù)據(jù)庫訪問速度是MySQL的10倍以上。Mongo的并發(fā)讀寫效率不是特別出色,根據(jù)官方提供的性能測試表明,大約每秒可以處理0.5萬-1.5次讀寫請求。

由于Mongo可以支持復(fù)雜的數(shù)據(jù)結(jié)構(gòu),而且?guī)в袕姶蟮臄?shù)據(jù)查詢功能,因此非常受到歡迎,很多項目都考慮用MongoDB來替代MySQL來實現(xiàn)不是特別復(fù)雜的Web應(yīng)用。

68PPT課件MongoDB簡介1.數(shù)據(jù)結(jié)構(gòu)Mongo主要解決的是海量數(shù)據(jù){ name:"lemo", age:"12", address:{ city:"suzhou", country:"china", code:215000 }, scores:[ {"name":"english","grade:3.0}, {"name":"chinese","grade:2.0} ]}69PPT課件{69PPT課件特點:高性能、易部署、易使用,存儲數(shù)據(jù)非常方便。主要功能特性有:面向集合存儲,易存儲對象類型的數(shù)據(jù)。模式自由。支持動態(tài)查詢。支持完全索引,包含內(nèi)部對象。支持查詢。支持復(fù)制和故障恢復(fù)。使用高效的二進制數(shù)據(jù)存儲,包括大型對象(如視頻等)。自動處理碎片,以支持云計算層次的擴展性支持Python,PHP,Ruby,Java,C,C#,Javascript,Perl及C++語言的驅(qū)動程序,社區(qū)中也提供了對Erlang及.NET等平臺的驅(qū)動程序。文件存儲格式為BSON(一種JSON的擴展)??赏ㄟ^網(wǎng)絡(luò)訪問。70PPT課件特點:70PPT課件功能:面向集合的存儲:適合存儲對象及JSON形式的數(shù)據(jù)。動態(tài)查詢:Mongo支持豐富的查詢表達式。查詢指令使用JSON形式的標記,可輕易查詢文檔中內(nèi)嵌的對象及數(shù)組。完整的索引支持:包括文檔內(nèi)嵌對象及數(shù)組。Mongo的查詢優(yōu)化器會分析查詢表達式,并生成一個高效的查詢計劃。查詢監(jiān)視:Mongo包含一個監(jiān)視工具用于分析數(shù)據(jù)庫操作的性能。復(fù)制及自動故障轉(zhuǎn)移:Mongo數(shù)據(jù)庫支持服務(wù)器之間的數(shù)據(jù)復(fù)制,支持主-從模式及服務(wù)器之間的相互復(fù)制。復(fù)制的主要目標是提供冗余及自動故障轉(zhuǎn)移。高效的傳統(tǒng)存儲方式:支持二進制數(shù)據(jù)及大型對象(如照片或圖片)自動分片以支持云級別的伸縮性:自動分片功能支持水平的數(shù)據(jù)庫集群,可動態(tài)添加額外的機器。71PPT課件功能:71PPT課件適用場合:網(wǎng)站數(shù)據(jù):Mongo非常適合實時的插入,更新與查詢,并具備網(wǎng)站實時數(shù)據(jù)存儲所需的復(fù)制及高度伸縮性。緩存:由于性能很高,Mongo也適合作為信息基礎(chǔ)設(shè)施的緩存層。在系統(tǒng)重啟之后,由Mongo搭建的持久化緩存層可以避免下層的數(shù)據(jù)源過載。大尺寸,低價值的數(shù)據(jù):使用傳統(tǒng)的關(guān)系型數(shù)據(jù)庫存儲一些數(shù)據(jù)時可能會比較昂貴,在此之前,很多時候程序員往往會選擇傳統(tǒng)的文件進行存儲。高伸縮性的場景:Mongo非常適合由數(shù)十或數(shù)百臺服務(wù)器組成的數(shù)據(jù)庫。Mongo的路線圖中已經(jīng)包含對MapReduce引擎的內(nèi)置支持。用于對象及JSON數(shù)據(jù)的存儲:Mongo的BSON數(shù)據(jù)格式非常適合文檔化格式的存儲及查詢。72PPT課件適用場合:72PPT課件Redis,Memcache,mongoDB的區(qū)別73PPT課件Redis,Memcache,mongoDB的區(qū)別73PPT1、性能都比較高,性能對我們來說應(yīng)該都不是瓶頸總體來講,TPS方面redis和memcache差不多,要大于mongodb2、操作的便利性memcache數(shù)據(jù)結(jié)構(gòu)單一redis豐富一些,數(shù)據(jù)操作方面,redis更好一些,較少的網(wǎng)絡(luò)IO次數(shù)mongodb支持豐富的數(shù)據(jù)表達,索引,最類似關(guān)系型數(shù)據(jù)庫,支持的查詢語言非常豐富3、內(nèi)存空間的大小和數(shù)據(jù)量的大小redis在2.0版本后增加了自己的VM特性,突破物理內(nèi)存的限制;可以對keyvalue設(shè)置過期時間(類似memcache)memcache可以修改最大可用內(nèi)存,采用LRU算法mongoDB適合大數(shù)據(jù)量的存儲,依賴操作系統(tǒng)VM做內(nèi)存管理,吃內(nèi)存也比較厲害,服務(wù)不要和別的服務(wù)在一起74PPT課件1、性能74PPT課件4、可用性(單點問題)對于單點問題,redis,依賴客戶端來實現(xiàn)分布式讀寫;主從復(fù)制時,每次從節(jié)點重新連接主節(jié)點都要依賴整個快照,無增量復(fù)制,因性能和效率問題,所以單點問題比較復(fù)雜;不支持自動sharding,需要依賴程序設(shè)定一致hash機制。一種替代方案是,不用redis本身的復(fù)制機制,采用自己做主動復(fù)制(多份存儲),或者改成增量復(fù)制的方式(需要自己實現(xiàn)),一致性問題和性能的權(quán)衡Memcache本身沒有數(shù)據(jù)冗余機制,也沒必要;對于故障預(yù)防,采用依賴成熟的hash或者環(huán)狀的算法,解決單點故障引起的抖動問題。mongoDB支持master-slave,replicaset(內(nèi)部采用paxos選舉算法,自動故障恢復(fù)),autosharding機制,對客戶端屏蔽了故障轉(zhuǎn)移和切分機制。75PPT課件4、可用性(單點問題)75PPT課件5、可靠性(持久化)對于數(shù)據(jù)持久化和數(shù)據(jù)恢復(fù),redis支持(快照、AOF):依賴快照進行持久化,aof增強了可靠性的同時,對性能有所影響memcache不支持,通常用在做緩存,提升性能;MongoDB從1.8版本開始采用binlog方式支持持久化的可靠性6、數(shù)據(jù)一致性(事務(wù)支持)Memcache在并發(fā)場景下,用cas保證一致性redis事務(wù)支持比較弱,只能保證事務(wù)中的每個操作連續(xù)執(zhí)行mongoDB不支持事務(wù)7、數(shù)據(jù)分析mongoDB內(nèi)置了數(shù)據(jù)分析的功能(mapreduce),其他不支持8、應(yīng)用場景redis:數(shù)據(jù)量較小的更性能操作和運算上memcache:用于在動態(tài)系統(tǒng)中減少數(shù)據(jù)庫負載,提升性能;做緩存,提高性能(適合讀多寫少,對于數(shù)據(jù)量比較大,可以采用sharding)MongoDB:主要解決海量數(shù)據(jù)的訪問效率問題76PPT課件5、可靠性(持久化)76PPT課件在MongoDB中,盡量避免進行比較大的skip操作,比如在分頁中,如果你能知道需要獲取數(shù)據(jù)的上一條score是多少,那么可能能夠用下面的方法來獲取你要的數(shù)據(jù),而不是通過一次很大的skip操作。

db.scores.find({lid:lid,score:{$lt:last_score}})。sort({score:-1})。limit(20)如果你需要進行比較大的skip操作或者count比較大的數(shù)量,那么可以考慮采用Redis的SortedSets來做。77PPT課件在MongoDB中,盡量避免進行比較大的skip操作,比如在謝謝大家78PPT課件謝謝大家78PPT課件Node.js79PPT課件Node.js1PPT課件Node.js簡介簡單的說Node.js就是運行在服務(wù)端的JavaScript。Node.js是一個基于ChromeJavaScript運行時建立的一個平臺。Node.js是一個事件驅(qū)動I/O服務(wù)端JavaScript環(huán)境(由C++編寫),基于Google的V8引擎,V8引擎執(zhí)行Javascript的速度非???,性能非常好。80PPT課件Node.js簡介簡單的說Node.js就是運行在服務(wù)端

Node.js的工作原理用戶Request用戶Request用戶RequestNode.js進程81PPT課件Node.js的工作原理用戶Request用戶RequesPhp模型

用戶Request用戶Request用戶RequestAPACHEPHP線程PHP線程PHP線程處理Request處理Request處理Request82PPT課件Php模型用戶Request用戶Request用戶RequeNodeJS優(yōu)缺點及適用場景討論NodeJS的特點NodeJS帶來的對系統(tǒng)瓶頸的解決方案NodeJS的優(yōu)缺點適合NodeJS的場景83PPT課件NodeJS優(yōu)缺點及適用場景討論NodeJS的特點5PPT課NodeJS的特點1.它是一個Javascript運行環(huán)境(C++實現(xiàn))2.依賴于ChromeV8引擎進行代碼解釋3.事件驅(qū)動4.非阻塞I/O5.輕量、可伸縮,適于實時數(shù)據(jù)交互應(yīng)用6.單進程,單線程7.模塊化編程8.事件輪詢(eventloop)84PPT課件NodeJS的特點1.它是一個Javascript運行環(huán)境NodeJS帶來的對系統(tǒng)瓶頸的解決方案它的出現(xiàn)確實能為我們解決現(xiàn)實當(dāng)中系統(tǒng)瓶頸提供了新的思路和方案,下面我們看看它能解決什么問題。1.并發(fā)連接舉個例子,想象一個場景,我們在銀行排隊辦理業(yè)務(wù),我們看看下面兩個模型。85PPT課件NodeJS帶來的對系統(tǒng)瓶頸的解決方案它的出現(xiàn)確實能為我們解(1)系統(tǒng)線程模型:這種模型的問題顯而易見,服務(wù)端只有一個線程,并發(fā)請求(用戶)到達只能處理一個,其余的要先等待,這就是阻塞,正在享受服務(wù)的請求阻塞后面的請求了。86PPT課件這種模型的問題顯而易見,服務(wù)端只有一個線程,并發(fā)請求(用戶)(2)多線程、線程池模型:這個模型已經(jīng)比上一個有所進步,它調(diào)節(jié)服務(wù)端線程的數(shù)量來提高對并發(fā)請求的接收和響應(yīng),但并發(fā)量高的時候,請求仍然需要等待,它有個更嚴重的問題。到代碼層面上來講,我們看看客戶端請求與服務(wù)端通訊的過程:87PPT課件(2)多線程、線程池模型:這個模型已經(jīng)比上一個有所進步,它調(diào)服務(wù)端與客戶端每建立一個連接,都要為這個連接分配一套配套的資源,主要體現(xiàn)為系統(tǒng)內(nèi)存資源,以PHP為例,維護一個連接可能需要20M的內(nèi)存。這就是為什么一般并發(fā)量一大,就需要多開服務(wù)器。那么NodeJS是怎么解決這個問題的呢?我們來看另外一個模型,想象一下我們在快餐店點餐吃飯的場景。88PPT課件服務(wù)端與客戶端每建立一個連接,都要為這個連接分配一套配套的資(3)異步、事件驅(qū)動模型我們同樣是要發(fā)起請求,等待服務(wù)器端響應(yīng);但是與銀行例子不同的是,這次我們點完餐后拿到了一個號碼,拿到號碼,我們往往會在位置上等待,而在我們后面的請求會繼續(xù)得到處理,同樣是拿了一個號碼然后到一旁等待,接待員能一直進行處理。等到飯菜做號了,會喊號碼,我們拿到了自己的飯菜,進行后續(xù)的處理(吃飯)。這個喊號碼的動作在NodeJS中叫做回調(diào)(Callback),能在事件(燒菜,I/O)處理完成后繼續(xù)執(zhí)行后面的邏輯(吃飯),這體現(xiàn)了NodeJS的顯著特點,異步機制、事件驅(qū)動整個過程沒有阻塞新用戶的連接(點餐),也不需要維護已經(jīng)點餐的用戶與廚師的連接。89PPT課件(3)異步、事件驅(qū)動模型我們同樣是要發(fā)起請求,等待服務(wù)器端響基于這樣的機制,理論上陸續(xù)有用戶請求連接,NodeJS都可以進行響應(yīng),因此NodeJS能支持比Java、PHP程序更高的并發(fā)量雖然維護事件隊列也需要成本,再由于NodeJS是單線程,事件隊列越長,得到響應(yīng)的時間就越長,并發(fā)量上去還是會力不從心??偨Y(jié)一下NodeJS是怎么解決并發(fā)連接這個問題的:更改連接到服務(wù)器的方式,每個連接發(fā)射(emit)一個在NodeJS引擎進程中運行的事件(Event),放進事件隊列當(dāng)中,而不是為每個連接生成一個新的OS線程(并為其分配一些配套內(nèi)存)。90PPT課件基于這樣的機制,理論上陸續(xù)有用戶請求連接,NodeJS都可以2.I/O阻塞NodeJS解決的另外一個問題是I/O阻塞,看看這樣的業(yè)務(wù)場景:需要從多個數(shù)據(jù)源拉取數(shù)據(jù),然后進行處理。(1)串行獲取數(shù)據(jù),這是我們一般的解決方案,以PHP為例假如獲取profile和timeline操作各需要1S,那么串行獲取就需要2S。91PPT課件2.I/O阻塞13PPT課件(2)NodeJS非阻塞I/O,發(fā)射/監(jiān)聽事件來控制執(zhí)行過程NodeJS遇到I/O事件會創(chuàng)建一個線程去執(zhí)行,然后主線程會繼續(xù)往下執(zhí)行的,因此,拿profile的動作觸發(fā)一個I/O事件,馬上就會執(zhí)行拿timeline的動作,兩個動作并行執(zhí)行,假如各需要1S,那么總的時間也就是1S。它們的I/O操作執(zhí)行完成后,發(fā)射一個事件,profile和timeline,事件代理接收后繼續(xù)往下執(zhí)行后面的邏輯,這就是NodeJS非阻塞I/O的特點。92PPT課件(2)NodeJS非阻塞I/O,發(fā)射/監(jiān)聽事件來控制執(zhí)行過程總結(jié)一下:Java、PHP也有辦法實現(xiàn)并行請求(子線程),但NodeJS通過回調(diào)函數(shù)(Callback)和異步機制會做得很自然。三.NodeJS的優(yōu)缺點優(yōu)點:1.高并發(fā)(最重要的優(yōu)點,據(jù)說可以應(yīng)付百萬級并發(fā))2.適合I/O密集型應(yīng)用缺點:1.不適合CPU密集型應(yīng)用;CPU密集型應(yīng)用給Node帶來的挑戰(zhàn)主要是:由于JavaScript單線程的原因,如果有長時間運行的計算(比如大循環(huán)),將會導(dǎo)致CPU時間片不能釋放,使得后續(xù)I/O無法發(fā)起;解決方案:分解大型運算任務(wù)為多個小任務(wù),使得運算能夠適時釋放,不阻塞I/O調(diào)用的發(fā)起;2.只支持單核CPU,不能充分利用CPU3.可靠性低,一旦代碼某個環(huán)節(jié)崩潰,整個系統(tǒng)都崩潰原因:單進程,單線程解決方案:(1)Nnigx反向代理,負載均衡,開多個進程,綁定多個端口;(2)開多個進程監(jiān)聽同一個端口,使用cluster模塊;4.開源組件庫質(zhì)量參差不齊,更新快,向下不兼容5.Debug不方便,錯誤沒有stacktrace93PPT課件總結(jié)一下:Java、PHP也有辦法實現(xiàn)并行請求(子線程),但四.適合NodeJS的場景1.RESTfulAPI這是NodeJS最理想的應(yīng)用場景,可以處理數(shù)萬條連接,本身沒有太多的邏輯,只需要請求API,組織數(shù)據(jù)進行返回即可。它本質(zhì)上只是從某個數(shù)據(jù)庫中查找一些值并將它們組成一個響應(yīng)。由于響應(yīng)是少量文本,入站請求也是少量的文本,因此流量不高,一臺機器甚至也可以處理最繁忙的公司的API需求。2.統(tǒng)一Web應(yīng)用的UI層目前MVC的架構(gòu),在某種意義上來說,Web開發(fā)有兩個UI層,一個是在瀏覽器里面我們最終看到的,另一個在server端,負責(zé)生成和拼接頁面。不討論這種架構(gòu)是好是壞,但是有另外一種實踐,面向服務(wù)的架構(gòu),更好的做前后端的依賴分離。如果所有的關(guān)鍵業(yè)務(wù)邏輯都封裝成REST調(diào)用,就意味著在上層只需要考慮如何用這些REST接口構(gòu)建具體的應(yīng)用。那些后端程序員們根本不操心具體數(shù)據(jù)是如何從一個頁面?zhèn)鬟f到另一個頁面的,他們也不用管用戶數(shù)據(jù)更新是通過Ajax異步獲取的還是通過刷新頁面。3.大量Ajax請求的應(yīng)用例如個性化應(yīng)用,每個用戶看到的頁面都不一樣,緩存失效,需要在頁面加載的時候發(fā)起Ajax請求,NodeJS能響應(yīng)大量的并發(fā)請求??偠灾琋odeJS適合運用在高并發(fā)、I/O密集、少量業(yè)務(wù)邏輯的場景。94PPT課件四.適合NodeJS的場景16PPT課件花瓣網(wǎng)淘寶開放平臺API調(diào)用Nodejs版本實現(xiàn)C社區(qū)成功案例網(wǎng)易開源基于Node.js的游戲服務(wù)器框架pomeloNodeOS(NodeOS是采用NodeJS開發(fā)的一款友好的操作系統(tǒng))95PPT課件花瓣網(wǎng)淘寶開放平臺API調(diào)用Nodejs版本實現(xiàn)Cnode.EventLoop96PPT課件EventLoop18PPT課件什么是EventLoop?EventLoop是一個很重要的概念,指的是計算機系統(tǒng)的一種運行機制。JavaScript語言就采用這種機制,來解決單線程運行帶來的一些問題。本文參考C.AaronCois的《UnderstandingTheNode.jsEventLoop》,解釋什么是EventLoop,以及它與JavaScript語言的單線程模型有何關(guān)系。97PPT課件什么是EventLoop?本文參考C.AaronCo想要理解EventLoop,就要從程序的運行模式講起。運行以后的程序叫做"進程"(process),一般情況下,一個進程一次只能執(zhí)行一個任務(wù)。如果有很多任務(wù)需要執(zhí)行,不外乎三種解決方法。以JavaScript語言為例,它是一種單線程語言,所有任務(wù)都在一個線程上完成,即采用上面的第一種方法。一旦遇到大量任務(wù)或者遇到一個耗時的任務(wù),網(wǎng)頁就會出現(xiàn)"假死",因為JavaScript停不下來,也就無法響應(yīng)用戶的行為。你也許會問,JavaScript為什么是單線程,難道不能實現(xiàn)為多線程嗎?這跟歷史有關(guān)系。JavaScript從誕生起就是單線程。原因大概是不想讓瀏覽器變得太復(fù)雜,因為多線程需要共享資源、且有可能修改彼此的運行結(jié)果,對于一種網(wǎng)頁腳本語言來說,這就太復(fù)雜了。后來就約定俗成,JavaScript為一種單線程語言。(WorkerAPI可以實現(xiàn)多線程,但是JavaScript本身始終是單線程的。)98PPT課件想要理解EventLoop,就要從程序的運行模式講起。運行如果某個任務(wù)很耗時,比如涉及很多I/O(輸入/輸出)操作,那么線程的運行大概是下面的樣子。上圖的綠色部分是程序的運行時間,紅色部分是等待時間??梢钥吹剑捎贗/O操作很慢,所以這個線程的大部分運行時間都在空等I/O操作的返回結(jié)果。這種運行方式稱為"同步模式"(synchronousI/O)或"堵塞模式"(blockingI/O)。99PPT課件如果某個任務(wù)很耗時,比如涉及很多I/O(輸入/輸出)操作,那如果采用多線程,同時運行多個任務(wù),那很可能就是下面這樣。上圖表明,多線程不僅占用多倍的系統(tǒng)資源,也閑置多倍的資源,這顯然不合理。EventLoop就是為了解決這個問題而提出的。Wikipedia這樣定義:100PPT課件如果采用多線程,同時運行多個任務(wù),那很可能就是下面這樣。上圖EventLoop是一個程序結(jié)構(gòu),用于等待和發(fā)送消息和事件。簡單說,就是在程序中設(shè)置兩個線程:一個負責(zé)程序本身的運行,稱為"主線程";另一個負責(zé)主線程與其他進程(主要是各種I/O操作)的通信,被稱為"EventLoop線程"(可以譯為"消息線程")。101PPT課件EventLoop是一個程序結(jié)構(gòu),用于等待和發(fā)送消息和事件上圖主線程的綠色部分,還是表示運行時間,而橙色部分表示空閑時間。每當(dāng)遇到I/O的時候,主線程就讓EventLoop線程去通知相應(yīng)的I/O程序,然后接著往后運行,所以不存在紅色的等待時間。等到I/O程序完成操作,EventLoop線程再把結(jié)果返回主線程。主線程就調(diào)用事先設(shè)定的回調(diào)函數(shù),完成整個任務(wù)??梢钥吹剑捎诙喑隽顺壬目臻e時間,所以主線程得以運行更多的任務(wù),這就提高了效率。這種運行方式稱為"異步模式"(asynchronousI/O)或"非堵塞模式"(non-blockingmode)。這正是JavaScript語言的運行方式。單線程模型雖然對JavaScript構(gòu)成了很大的限制,但也因此使它具備了其他語言不具備的優(yōu)勢。如果部署得好,JavaScript程序是不會出現(xiàn)堵塞的,這就是為什么node.js平臺可以用很少的資源,應(yīng)付大流量訪問的原因。102PPT課件上圖主線程的綠色部分,還是表示運行時間,而橙色部分表示空閑時Node.js

語法103PPT課件Node.js

語法25PPT課件第一個Node.js程序:HelloWorld!以下是我們的第一個Node.js程序:console.log("HelloWorld");保存該文件,并通過Node.js來執(zhí)行:nodehelloworld.js程序執(zhí)行后,正常的話,就會在終端輸出HelloWorld。104PPT課件第一個Node.js程序:HelloWorld!26PPTNode.js安裝配置window和Linux上安裝Node.js的方法Node.js安裝包及源碼下載地址為:/download/。根據(jù)不同平臺系統(tǒng)選擇你需要的Node.js安裝包。注意:Linux上安裝Node.js需要安裝Python2.6或2.7,不建議安裝Python3.0以上版本。105PPT課件Node.js安裝配置根據(jù)不同平臺系統(tǒng)選擇你需要的NodeWindowv上安裝Node.jsWindows安裝包(.msi):32位安裝包下載地址:/dist/v0.10.26/node-v0.10.26-x86.msi64位安裝包下載地址:/dist/v0.10.26/x64/node-v0.10.26-x64.msi安裝步驟:步驟1:雙擊下載后的安裝包node-v0

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論