1. 程式人生 > >Node單執行緒高併發原理

Node單執行緒高併發原理

一、node是如何處理web請求的

瀏覽器中的js是單執行緒的,node也是單執行緒的。這個單執行緒相當於一個大管家,一切大小事務都要經過他的手才能辦成,它總是把IO任務放入到任務池中。
雖然說是單執行緒,但是node也有一個執行緒池專門負責執行任務池中的任務,它們把任務完成之後會告知主執行緒以接下來利用CPU完成處理。
關鍵在於理清哪些任務是主執行緒做的,哪些任務是執行緒池做的。
對於IO操作(例如檔案讀取、資料庫讀取、網路請求等),基本全部是執行緒池完成的(IO操作也有阻塞式的寫法);對於計算任務,都是主執行緒完成的。
不要小看IO操作佔用的時間,node的重要優勢就是把IO操作放到了主執行緒之外,從而讓主執行緒騰出手來去處理更多的請求。
node的執行緒池基於libuv這個庫。

node技術的底層依賴:

  • V8:Google 推出的 Javascript VM,也是 Node.js 為什麼使用的是 Javascript的關鍵,它為 Javascript提供了在非瀏覽器端執行的環境,它的高效是 Node.js 之所以高效的原因之一。
  • Libuv:它為 Node.js 提供了跨平臺,執行緒池,事件池,非同步 I/O 等能力,是 Node.js 如此強大的關鍵。
  • C-ares:提供了非同步處理 DNS 相關的能力。
  • http_parser、OpenSSL、zlib 等:提供包括 http 解析、SSL、資料壓縮等其他的能力。

二、其它語言是如何處理web請求的

以python為例,gunicorn伺服器可以指定worker數,表示可以同時處理的任務數。即便這些任務都是CPU密集型操作,gunicorn也能夠最多支援和worker數相等的請求。而node最多隻能支援一個CPU密集型任務。
簡言之,node相當於一個worker,但是這個worker效率比較高(因為把IO和計算分離開了)。
實際上,node可以通過開很多個程序,通過nginx負載均衡來實現多個worker,這樣完全可以達到和其它語言相同的效果。
簡言之,開多個worker誰都會。node的優勢在於這個優秀的單執行緒。
開多個worker應該是優化的最後一步,是實在想不出更好辦法之後的辦法。node的創新之處就在於IO和計算分離,從而將併發量提高了許多。
IO和計算分離是一種思想,並非只能用js實現,其它語言也可以借鑑。

三、node的優勢和劣勢

  • node擅長執行IO密集型任務,不善於執行CPU密集型任務。
  • node的效率比傳統阻塞式web服務高,為啥以前沒有想到使用事件驅動模型把IO和計算進行分離?因為分離是有代價的,node非同步模式帶來了大量的回撥,回撥一旦太深,程式碼可讀性極差。
  • node的主執行緒不能崩,主執行緒一崩整個服務全掛掉。因此一定要接住異常,這個問題不算劣勢,因為很容易解決。

四、node如何實現多個worker

cluster模組已經成為node的標準模組了,這個模組賦予了node多worker的能力。使用nginx+多個例項的方法需要佔用多個埠,cluster則能夠讓多個worker共用同一埠。
原來的單執行緒模型處理計算密集型任務的執行緒只有一個,即主執行緒;處理IO的執行緒有多個。現在cluster通過開闢多個處理計算密集型任務的執行緒實現了多worker。

參考資料

一篇cluster的詳細講解
https://blog.csdn.net/leohzj/article/details/50462231