如果您使用 PM2 來管理 Node.js 進程,您可能已經注意到它支援叢集模式。這種模式允許 Node.js 創建多個進程。當您將叢集模式下的執行個體數量設定為 max 時,PM2 會自動建立與伺服器上可用 CPU 核心相對應的 Node 流程數。
PM2 透過利用 Node.js 的 Cluster 模組來實現這一點。該模組解決了 Node.js 的單線程特性,傳統上限制了其利用多個 CPU 核心的能力。但是 Cluster 模組內部是如何運作的呢?進程之間如何通訊?多個進程如何監聽同一個連接埠? Node.js 如何將請求分發到這些進程?如果您對這些問題感到好奇,請繼續閱讀。
Node.js 工作進程是使用 child_process.fork() 方法建立的。這意味著有一個父進程和多個子進程。程式碼通常如下圖所示:
const cluster = require('cluster'); const os = require('os'); if (cluster.isMaster) { for (let i = 0, n = os.cpus().length; i < n; i++) { cluster.fork(); } } else { // Start the application }
如果您研究過作業系統,您可能熟悉 fork() 系統呼叫。呼叫進程是父進程,而新建立的進程是子進程。這些子進程與父進程共享相同的資料段和堆疊,但它們的物理記憶體空間不一定共享。在 Node.js 叢集中,master 進程偵聽連接埠並將傳入請求分發到 worker 進程。這涉及到解決三個核心主題:進程間通訊 (IPC)、負載平衡策略和多進程連接埠監聽。
master程式使用process.fork()建立子程序。這些進程之間的通訊是透過 IPC 通道 處理的。作業系統提供了多種進程間通訊的機制,例如:
訊息傳遞
透過發送和接收訊息來處理交換資料。
訊號量
信號量是系統分配的狀態值。缺乏控制的進程將被迫在特定的檢查點停止,等待繼續進行的信號。當僅限於二進位值(0 或 1)時,此機制稱為「互斥鎖」(互斥鎖)。
管
管道連接兩個進程,允許一個進程的輸出作為另一個進程的輸入。這可以使用管道系統呼叫來創建。 | 的 | shell 腳本中的命令是這種機制的一個常見範例。
Node.js 使用基於事件的機制在父進程和子進程之間進行通訊。這是父進程向子程序發送 TCP 伺服器句柄的範例:
const cluster = require('cluster'); const os = require('os'); if (cluster.isMaster) { for (let i = 0, n = os.cpus().length; i < n; i++) { cluster.fork(); } } else { // Start the application }
如前所述,所有請求均由 master 進程分發。確保伺服器負載在工作進程之間均勻分佈需要負載平衡策略。 Node.js 預設使用 round-robin 演算法。
輪詢方法是 Nginx 也採用的常見負載平衡演算法。它的工作原理是按順序將傳入請求分發到每個進程,從第一個進程開始,到達最後一個進程後循環返回。然而,該方法假設所有進程的處理能力相同。在請求處理時間變化較大的場景下,可能會出現負載不平衡的情況。
為了解決這個問題,Nginx 經常使用加權循環(WRR),其中伺服器被分配不同的權重。選擇權重最高的伺服器,直到其權重減少到零,此時根據新的權重序列重新開始循環。
您可以透過設定 NODE_CLUSTER_SCHED_POLICY 環境變數或透過 cluster.setupMaster(options) 配置來調整 Node.js 中的負載平衡策略。結合 Nginx 進行多機叢集和 Node.js Cluster 進行單機多進程平衡是常見的做法。
在 Node.js 的早期版本中,偵聽相同連接埠的多個進程會競爭傳入連接,從而導致負載分佈不均勻。後來透過循環賽策略解決了這個問題。目前方法的工作原理如下:
本質上,主進程監聽連接埠並使用定義的策略(例如,循環)將連線指派給工作進程。這種設計消除了worker之間的競爭,但要求master進程高度穩定。
本文以 PM2 的 Cluster 模式為切入點,探討了 Node.js 的 Cluster 模組實作多進程應用程式背後的核心原理。我們將重點放在三個關鍵方面:進程間通訊、負載平衡和多進程連接埠監聽。
透過研究Cluster模組,我們可以看到很多基本原理和演算法是通用的。例如,循環演算法被用於作業系統進程調度和伺服器負載平衡。 master-worker架構類似Nginx中的多進程設計。同樣,信號量和管道等機制在各種編程範例中也無所不在。
雖然新技術不斷湧現,但它們的基礎始終如一。了解這些核心概念使我們能夠自信地推斷和適應新的挑戰。
Leapcell 是用於 Web 託管、非同步任務和 Redis 的下一代無伺服器平台:
多語言支援
免費部署無限個專案
無與倫比的成本效率
簡化的開發者體驗
輕鬆的可擴充性和高效能
在文件中探索更多資訊!
在 X 上追蹤我們:@LeapcellHQ
閱讀我們的部落格
以上是了解 Node.js 叢集:核心概念的詳細內容。更多資訊請關注PHP中文網其他相關文章!