Nodejs 圖解NodeJS【基於事件、回調的單線程高性能服務器】原理

nodejs的機制是單線程,這個線程裏面,有一個事件循環機制,處理全部的請求。如圖所示。在事件處理過程當中,它會智能地將一些涉及到IO、網絡通訊等耗時比較長的操做,交由worker threads去執行,執行完了再回調,這就是所謂的異步IO非阻塞吧。可是,那些非IO操做,只用CPU計算的操做,它就本身扛了,好比算什麼斐波那契數列之類。它是單線程,這些本身扛的任務要一個接着一個地完成,前面那個沒完成,後面的只能乾等。所以,對CPU要求比較高的CPU密集型任務多的話,就有可能會形成號稱高性能,適合高併發的node.js服務器反應緩慢。javascript

圖解NodeJS【基於事件、回調的單線程高性能服務器】原理

輪詢技術的缺點在於應用程序要主動調用,會形成佔用較多CPU時間片,性能較爲低下。html

理想的異步I/O應該是應用程序發起異步調用,而不須要進行輪詢,進而處理下一個任務,只需在I/O完成後經過信號或是回調將數據傳遞給應用程序便可。java

Node只是表面暴露給用戶的javascript代碼是單線程的,底層仍是多線程的。

Node.js選擇的異步I/O方案:因爲Windows平臺和*nix平臺的差別,Node.js提供了libuv來做爲抽象封裝層,使得全部平臺兼容性的判斷都由這一層次來完成,保證上層的Node.js與下層的libeio/libev及IOCP之間各自獨立。Node.js在編譯期間會判斷平臺條件,選擇性編譯unix目錄或是win目錄下的源文件到目標程序中。node

每次循環中,它會調用IOCP相關的GetQueuedCompletionStatus方法檢查是否線程池中有執行完的請求,若是存在,poll操做會將請求對象加入到loop的pending_reqs_tail屬性上。 另外一邊這個循環也會不斷檢查loop對象上的pending_reqs_tail引用,若是有可用的請求對象,就取出請求對象的result屬性做爲結果傳遞給oncomplete_sym執行,以此達到調用JavaScript中傳入的回調函數的目的。 至此,整個異步I/O的流程完成結束。其流程以下:git

初探Node.js的異步I/O實現

使用Node的時候,會在javascript觸發一些命令調用方法,這些方法會被包裝成一個對象,放入線程池,而後前面的方法就返回了,繼續執行下面的JS代碼。

線程池中採用多線程的方式執行,執行完的對象放入事件循環隊列。

事件循環隊列採用相似while(true)這種循環的方式,不斷的查看是否有事件,而且讀取是否包含回調,因爲前面回調函數被包裝到對象中,這裏直接調用執行就能夠了。

---------------------------------------------------------------------------------------------------------------------------------------------------------------------github

  • npm:NodeJs包管理器
  • express:服務器端比較流行的MVC框架,處理服務請求,路由轉發,邏輯處理
  • mongoose:mongodb包裝,更方便使用數據庫
  • :實現服務端和客戶端socket通訊解決方案
  • backbone:客戶端MVC框架,編寫客戶端應用(豆瓣說)
  • coffeescript:提升JavaScript的可讀性,健壯性
  • zombie:瀏覽器子集,編寫html解析器,輕形javascript客戶端測試

------------------------------------------------------------------------------------------------------------------------------------------------------------------------mongodb

一、進入 http://nodejs.org 下載開發環境chrome

http://Expressjs.com 下載安裝Express  npm install -g express數據庫

繼續安裝ejs:npm install ejsexpress

若是要想運行Node.js程序,則如今只可以使用「node app.js」,而這樣的運行方式,若是在app.js文件修改以後每每須要從新啓動才能夠加載新的內容,這對於開發是很是不方便的, 爲此,可使用一個supervisor組件包,它能夠動態的加載修改以後的開發程序。

下載安裝supervisor

npm install -g supervisor

利用supervisor方式運行程序

supervisor app.js

 

二、 調試代碼:進入npm目錄安裝supervisor。 -g 表示全局模式 
npm install -supervisor -g
 安裝supervisor 來控制調試代碼。 不須要每次中止重啓node.js的服務
使用supervisor app.js啓動
 
三、開發工具 WebStorm http://www.jetbrains.com    tools 下載30天試用版
 
四、回調函數:調用時所作的工做知識將異步式IO請求發送給了操做系統,而後當即返回並執行後面的語句,執行完之後進入事件循環監聽事件,當fs接受到IO請求完成的事件時。事件循環會主動調用回調函數完成後續工做。同步則是阻塞等待完成後,繼續執行。
 
五、事件
            a.普通事件的使用
                    //聲明事件對象`
                    var EventEmitter=require('events').EventEmitter;
                    var event=new EventEmitter();
                    //註冊事件
                     event.on('some_event',function(){
                        console.log('這是一個自定義的事件');
                    });
                    //觸發事件
                    setTimeout(function(){
                        event.emit('some_event');
                    },1000);
            b.Node.js的事件循環機制
                (1)Node.js在何時進入事件循環呢?
                        Node.js程序是由事件循環開始,到事件循環結束,全部的邏輯都是事件的回調函數。
                (2)如何使用自定義事件呢?
                        事件的回調函數在執行的過程當中,可能會發出IO請求或直接發射(emit)事件,執行完畢後再返回事件循環。

 

六、模塊:Node.js提供了exports和require兩個對象,其中exports是模塊公開的接口,require用於從外部獲取一個模塊的接口,即獲取模塊的exports對象。exports自己僅僅是一個普通的空對象,即{},它是專門用來聲明接口

 

七、包是在模塊基礎上更深一步的抽象,Node.js的包相似於C/C++的函數庫或者java的類庫,它講某個獨立的功能封裝起來,用於發佈、更新、依賴管理的版本控制。npm解決包的發佈和獲取需求。

 

 Node.js包管理器,即npm是Node.js官方提供的包管理工具,它已經成了Node.js包的標準發佈平臺,用於Node.js包的發佈、傳播、依賴控制。
                (1)獲取一個包
                        npm [install/i] [package_name]       
                       例如安裝express包:
                        npm i express
                 卸載包:
                    npm uninstall 包名 [-g]
                  查看當前全部包:
                    npm list
                   ....
                    幫助連接: http://www.cnblogs.com/bluefrog/archive/2012/08/14/2639085.html
                (2)本地模式和全局模式
                        npm在默認狀況下會從 http://npmjs.org搜索或下載包,講包安裝到當前目錄的node_modules  
                        a.默認是npm install 包名   做爲本地模式
                        b.全局模式
                            npm install -g 包名
                        c.區別和用法
                                由於本地模式不會註冊PATH環境變量,舉例,咱們安裝supervisor是爲了在命令行中運行它,譬如直接運行supervisor scirpt.js。
                                npm本地模式僅僅把包安裝到了node_modules子目錄下,其中的bin目錄沒有包含在PATH環境變量中,調用。不能直接在命令行中
                                 使用全局模式安裝的包並不能直接在javascript文件中require得到,由於require不會搜索/usr/local/lib/node_modules。
                    
                        通俗講: 當咱們要把某個包做爲工程運行時的一部分時,經過本地模式獲取,若是在命令行下使用,則使用全局模式。
                        d.包的發佈
                               首選確保具有CommonJS爲基礎包的規範,但與CommJS並不徹底一致,其主要差異在於必填字段的不一樣,經過使用npm init能夠根據交互式問答產生一個符合標準的package.json
                         dos進入這個目錄運行 npm init獲得package.json的文件,改爲本身的文件等信息
                        而後進入package.json所在目錄運行  npm publish  就完成了發佈
                         如何更新包?
                            若是你的包內容有改動,則在版本上做改動,運行npm publish
                            訪問 http://search/npmjs.org/就能夠找到本身剛剛發佈的包了                          如何取消發佈:
                               npm unpublish     

 

八、調試代碼

                        在eclipse裝插件
                                地址是 http://chromedevtools.googlecode.com/svn/update/dev/
                                 在debug中配置  端口爲5858 
                        在命令行運行js文件的時候
                                node --debug-brk=5858 文件名.js
                        如今就在ecplise中啓動debug就能夠跟斷點了
                    Google Dart
 
九、全局對象與全局變量:全部屬性均可以在程序的任何地方訪問,即全局變量。在JavaScript中,一般window是全局對象,而Node.js的全局對象是global,全部全局變量都是global對象的屬性,如:console、process等。
 
十、
相關文章
相關標籤/搜索