一、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