博客 / 詳情

返回

Node.js Event Loop 處理的幾大週期介紹

Node.js Event Loop 處理的幾大週期如下圖所示:

  • Timer:通過 setTimeout() 或 setInterval() 安排的一切都將在這裏處理。
  • IO 回調:這裏將處理大部分回調。 由於 Node.js 中的所有用户態代碼基本上都在回調中(例如,對傳入 http 請求的回調會觸發級聯回調),這就是用户態代碼。
  • IO輪詢:輪詢下一次運行要處理的新事件。
  • Set Immediate:運行通過 setImmediate() 註冊的所有回調。
  • close:這裏處理了所有 on('close') 事件回調。

實際上 Node 應用程序中發生的一切都通過事件循環運行。這意味着,如果我們可以從中獲取指標,它們應該會為我們提供有關應用程序整體健康狀況和性能的寶貴信息。

如果應用程序處於空閒狀態,這意味着沒有待處理的任務(定時器、回調等),全速運行這些階段是沒有意義的,因此事件循環將適應這種情況並在 等待新的外部事件進入的輪詢階段。

這也意味着,無負載下的指標與高負載下與慢速後端通信的應用程序相似(低頻率、高持續時間)。

Event Loop Latency

事件循環延遲衡量在使用 setTimeout(X) 安排的任務真正得到處理之前還需要多長時間。

高事件循環延遲表示事件循環忙於處理回調。

Node.js 應用程序在單個線程上運行。 在多核機器上,這意味着負載不會分佈在所有內核上。 使用 Node 附帶的集羣模塊,可以很容易地為每個 CPU 生成一個子進程。 每個子進程維護自己的事件循環,主進程透明地在所有子進程之間分配負載。

如前所述,libuv 將創建一個大小為 4 的線程池。可以通過設置環境變量 UV_THREADPOOL_SIZE 來覆蓋池的默認大小。
雖然這可以解決 I/O 密集型應用程序的負載問題,但在生產系統上進行這項改動之前,務必進行負載測試,因為更大的線程池可能仍會耗盡內存或 CPU.

user avatar momoko8443 頭像
1 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.