請問nodejs(Koa或者Egg)做的web服務(包括restful介面)是非同步非阻塞的嗎?
如果是,一定是嗎?
是的,框架是非同步非阻塞的。但你還要在你的代碼里控制不要用同步阻塞IO,以及任何耗時較長的同步方法--比如說解析一個大xml文件等。否則,你這個後端應用就還是阻塞的。
有不少朋友曾經和我說有些相應時間很短的IO操作是不是就用同步算了,比如說memcached和Redis。現實的血淚教訓是不行,IO操作受網路延時影響有時候會延時莫名增加,有時候tail latency會比較明顯,都會讓你的後端應用出現進程阻塞,這裡會有個放大效應,嚴重影響sla。
不了解Koa或者Egg,但是經常用Express。不過基本原理和node自身的構造更相關一些(而非其上的框架)。Node的本質是當運行JavaScript代碼時,代碼本身是阻塞的(JS單線程的緣故)。但是當你使用Node API時,非同步API可以選擇創建另一線程並在其之上執行讀寫任務。當JS本身運行完畢後,event loop會開始檢查非同步API的執行是否完成,如果完成的話會向js引擎v8要求運行對應callback里的代碼並提供對應處理完成的數據。也就是說node背後其實有很多線程用來執行具體讀寫任務,但真正由你寫的javascript代碼本身永遠都是單線程阻塞運行的(除非你使用worker thread)
單線程,如果不是非同步的,怎麼並發處理多請求。
是的,正好應了node.js簡介事件驅動非阻塞
nodejs的io模型是非同步非阻塞的,大部分介面都是,只要不寫cpu密集型的代碼,整體性能就不會差
Nodejs的引擎v8是非同步非阻塞的,但是這個引擎由於非同步,會誕生諸多問題。
比如我在用oracledb做資料庫讀寫操作的時候,由於同時並發100+個操作,而這個庫是將一個操作分成很多個cb回調的,但是資料庫看來就亂套了,所以會有不可避免的但是又不可修復的各種線程佔用錯誤...
後來用.net多線程方式重寫了才流暢起來....
經驗就是,至多用來讀取一下redis,其他的嘛還是交給jvm或.net來,他們的更成熟
網路部分非同步,阻塞還是非阻塞忘記了,模糊libuv里用的是阻塞io
推薦閱讀: