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

剛開始瞭解Node感受很吊,各類說高性能,但是一直不理解爲何單線程會比多線程快?爲何異步IO比非阻塞IO快?所以,本篇在閱讀相關書籍後,根據本身的理解,整理此文,若有錯誤,僅表明理論不精,必當修改,以避免誤導他人。還請多多指正.....javascript

關於阻塞IO和非阻塞IO

系統內核只有兩種IO模式—— 阻塞IO和非阻塞IO。這裏的IO可不單單是讀取文件內容,而是更爲普遍的概念。好比Socket啊,網絡Socket,磁盤讀取等等,這些相比於CPU計算都是很耗時的。java

下圖爲阻塞IO的工做模式:linux

阻塞IO在須要獲取數據進行IO操做時,CPU會等待,當讀取完成後,再繼續運行。那麼很容易就能想到,若是讀取很耗時,CPU就會長期處於阻塞狀態,顯然效率很低。windows

再看看非阻塞IO:網絡

非阻塞IO在進行IO操做時,會直接返回。而後CPU該幹嗎幹嗎,只不過須要必定的策略來肯定什麼時間請求數據完成,這個時候就須要一些輪訓策略了,好比select poll等等。那麼這個也應該能想到,當有長期的IO操做,會白白執行大量的查詢操做,效率也不高。(固然目前的系統內的非阻塞IO都是很高級的玩法,滷煮也沒有仔細研究,就不獻醜了)多線程

異步IO與Node工做原理

經過上面兩種典型的IO操做,很顯然,一種理想的模型是,有IO操做時,系統去執行IO操做,CPU該幹嗎幹嗎,當請求數據完成後,就通知CPU繼續執行剛纔沒有完成的工做。異步

Node就是利用了javascript的回調函數思想,實現這種工做模式。函數

那麼爲何單線程的Node會效率很高呢?什麼又是事件機制呢?

原來,一直說的單線程,都是javascript端的,Node底層仍是使用c來實現,所以底層仍然是多線程的。只不過,Node基於不一樣的操做系統linux或者windows之上實現了一個封裝層,用戶執行的操做命令會轉交給這個封裝層,由它再去判斷操做系統,進而調用相應平臺的c代碼。性能

有點跑題了,簡單的說,就是Node只是表面暴露給用戶的javascript代碼是單線程的,底層仍是多線程的。

說到事件機制,就要上圖了!
操作系統

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

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

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

經過這三種階段,就實現了 【 異步請求——>回調 】 的工做模式。

相關文章
相關標籤/搜索