NodeJS學習

NodeJs是一種用JavaScript編寫,運行在Google V8引擎的服務端程序,在2009年出來,在經歷過幾個版本後,如今已經被運用在某些特定的地方,好比網站先後端分離,聊天室等。程序員

在看NodeJS的一些介紹的時候,常常會看到高併發和高性能兩個詞,這裏看一下爲何會高併發和高性能:編程

 1. NodeJS對於一個請求,再也不是建立一個線程,因此這就減小了建立線程帶來的性能損耗,性能就能夠上去,同時也避免了OS底層對進程內線程數的限制,併發就能夠上去。 後端

 2. NodeJS內部是基於事件循環的,並且是基於異步IO的,因此避免了CPU的上下文切換,一樣解決的系能損耗,服務器

可是這裏要注意一個問題:網絡

1. NodeJS進程並非真正意義的單線程,好比一個NodeJS請求,要進行網絡訪問,並將相應內容寫入到磁盤,實際上是有3個IO線程,1是一個http請求的IO線程,一個是網絡訪問的IO線程,還有一個是磁盤IO線程。 NodeJS的線程模型能夠理解爲一個工做線程,多個IO線程。 併發

下面是NodeJs的結構圖:前後端分離

其中Libuv是一個適配層,主要針對*nix和Windows下異步IO的適配,進程間通訊的適配。異步

看NodeJs的介紹,常常看到的就是異步, 這裏的異步本質就是操做系統的異步,因此這裏理解了操做系統的異步,也就理解了NodeJS的異步,關於同步,異步,阻塞和非阻塞,能夠參考 http://bbym010.iteye.com/blog/2100868 ide

關於異步能夠參考下面這種圖:異步編程

QQ截圖20160904194537.png

 

這個特性是在0.6版本之後才被加入進行的, 是爲了解決NodeJS服務器資源利用率不高的問題,其解決方案就是有一個Maste進程,在啓動的時候,再fork()多個work進程,Master監聽主端口(好比80),在接受到一個請求後,就會有一個連接句柄,把這個連接句柄發送到Work進程去。 

這裏面牽扯到進程間的通訊,這個通訊針對不一樣的操做系統進行了封裝,以下:

 

雖然NodeJs如今被運的地方不少,可是也仍是有一些問題

  1. 邏輯編寫麻煩:NodeJS的程序是基於異步回調的, 因此在編寫代碼的時候, 會有大量的回調代碼,這一點對於那些習慣編寫「順序」代碼的程序員有不小的影響。這個相比.Net程序仍是有差距(.Net程序能夠以同步的方式寫異步代碼),目前我查了資料,已經存在一些將異步轉爲同步的解決方法,還有一種解決方法就是修改語法,以同步的方式編寫代碼,而後修改編譯器或者運行時,將同步轉爲異步模式運行。 

  2. 單線程:NodeJS的運行時只有一條線程,基於事件循環來處理,這形成了兩個問題:

    1. 如今的服務器都是多核心的,而 NodeJS只運行在單核上,不可避免的對服務器的資源形成必定的浪費。

    2. 對IO密集型友好,對CPU密集型不友好,雖然NodeJS底層是基於V8的,性能很高,可是由於是單線程,稍微複雜的邏輯判斷就有可能阻塞事件循環。

目前NodeJS自身已經提出瞭解決方案,就是Cluster,本質就是父子進程的概念,由一個Master進程啓動多個Work進程,進程數和CPU核心相關,全部的請求通過Master進程,而後再分配到具體的Work線程,這個模型和Nginx的模型相似, Cluster模型能夠解決資源被浪費的狀況, 也能從必定程度上緩解CPU的問題,可是和傳統的Apache比起來,還有必定差距。

本篇博客部分圖片來自 《深刻淺出Node.js》

相關文章
相關標籤/搜索