Node.js 專一於實現 web 高性能的服務器,是一個讓 JavaScript 運行在服務器上的平臺。他使用 Chrome 瀏覽器的 V8 引擎做爲 JS 代碼的解釋工具,底層使用 C++ 進行開發,而 V8 引擎也正是基於 C++ 開發的。web
Node.js 並非一種新的語言,他是基於 JavaScript 實現的,可是他讓 JavaScript 煥發出了新的活力,將 JavaScript 的觸角伸到了服務器端。數據庫
Node.js 和傳統的服務器端程序的最大區別在於 Node.js 沒有 Web 容器的概念。通常來服務器程序好比 PHP、JSP、Python、Perl、Ruby 等都須要運行在 Web 容器中才能被訪問,最經常使用的 Web 容器好比說 Apache、Nginx 等。可是 Node.js 沒有!經過對於頂層路由的設計可以制定出很簡潔清晰的 URL。瀏覽器
Node.js 的另外一大特色在於他是單線程的,整個 Node.js 程序運行在單一的一個線程上。服務器
一個 Java Web 項目,用戶發起請求會爲其建立一個線程,而每一線程都須要佔用必定的內存,全部對於服務器的要求會隨着用戶數的增長而增長,硬件成本也相應提升。同時使用多線程會存在上下文切換和線程銷燬的開銷,若是使用單線程就能避免這些應爲多線程帶來的系統開銷,提升系統運行效率。多線程
Node.js 不會爲每一個用戶建立一個新的線程,而是使用同一個線程接收全部的請求。使用一個線程在面對多個用戶請求時,Node 不能像多線程那樣並行地對其進行處理。在單線程上咱們順次執行程序,在一個請求沒有執行完的時候,線程就會阻塞,下一個請求就沒法進行。函數
爲了應付單線程的阻塞問題,Node 使用了非阻塞 I/O 機制。工具
處理一個請求時最耗時的操做是各類 I/O 操做,最頻繁的就是對數據庫的讀寫操做,或者是對文件的讀寫操做。在單線程中若是執行到 I/O 操做,則線程會在此阻塞等待返回結果。性能
Node 爲了應付費時的 I/O 操做使用了非阻塞 I/O 模式。當程序一旦執行到了 I/O 操做的部分,則當即將 I/O 操做交給回調函數,本身則繼續執行後面的程序。spa
這裏就有兩點須要注意的。線程
一是執行回調函數以後的代碼不能依賴回調函數的結果。好比用戶登陸的操做,須要查詢數據庫驗進行校驗,以後的登陸操做須要依賴回調的結果,此時必須等待返回校驗結果才能進行登陸操做。
二是執行回調函數以後什麼時候再繼續執行。因此必需要有事件循環,回過頭來繼續執行操做,就須要不斷檢查線程上有沒有沒有處理完的事件,排隊實現他們。
所以 Node 的這條線程一直處於運行狀態不會阻塞,CPU 的利用率一直很高。
Node 的第三個特色就是事件驅動。也就是前面講的在線程執行 A 操做的過程當中採用回調函數的形式轉而處理 B 事件,在 B 事件處理完以後再去執行 B,如網上一張圖片所示:
事件在循環執行之中,當遇到 I/O 操做則採用回調函數處理,處理完的事件則會排隊等候再次執行,造成了一個個的事件環。
Node 經過非阻塞 I/O 的機制和事件驅動的方式讓單線程的程序實現了多線程的效果。讓一個線程永遠處於忙碌的狀態,不會形成資源的浪費。這樣就能下降硬件的成本卻不會影響程序執行的效率。