搜尋
首頁web前端js教程如何創建一個node.js群集以加速您的應用

How to Create a Node.js Cluster for Speeding Up Your Apps

核心要點

  • Node.js憑藉其事件驅動架構和非阻塞I/O API,成為處理高流量網站的熱門服務器端運行環境,允許異步請求處理。
  • Node.js的可擴展性是其被大型公司採用的關鍵特性。儘管默認情況下在單線程中運行並具有內存限制,但Node.js可以通過集群模塊將單個進程拆分為多個進程或工作進程來擴展應用程序。
  • Node.js集群模塊通過多次執行相同的Node.js進程來工作。它允許識別主進程並創建工作進程,這些工作進程可以共享服務器句柄並與父Node進程通信。
  • Node.js應用程序可以使用集群模塊進行並行化,允許多個進程同時運行。這提高了系統的效率,改善了應用程序性能,並增強了可靠性和正常運行時間。
  • 雖然Node.js集群模塊主要推薦用於Web服務器,但在仔細考慮工作進程之間的任務分配以及工作進程和主進程之間的有效通信的情況下,也可以將其用於其他應用程式.

Node.js作為服務器端運行環境越來越受歡迎,尤其是在高流量網站方面,統計數據也證明了這一點。此外,眾多框架的可用性使其成為快速原型設計的良好環境。 Node.js具有事件驅動的架構,利用非阻塞I/O API允許異步處理請求。 Node.js的一個重要且經常被忽視的特性是其可擴展性。事實上,這是某些大型公司在其平台中集成Node.js(例如Microsoft、Yahoo、Uber和Walmart)甚至將其服務器端操作完全遷移到Node.js(例如PayPal、eBay和Groupon)的主要原因。每個Node.js進程都在單個線程中運行,默認情況下,32位系統的內存限制為512MB,64位系統的內存限制為1GB。儘管可以在32位系統上將內存限制提高到約1GB,在64位系統上提高到約1.7GB,但內存和處理能力仍然可能成為各種進程的瓶頸。 Node.js為擴展應用程序提供的優雅解決方案是將單個進程拆分為多個進程或Node.js術語中的工作進程。這可以通過集群模塊實現。集群模塊允許您創建子進程(工作進程),這些子進程與主Node進程(主進程)共享所有服務器端口。在本文中,您將了解如何創建Node.js集群以加快應用程序的速度。

Node.js集群模塊:它是做什麼的以及如何工作

集群是在父Node進程下運行的類似工作進程的池。工作進程使用child_processes模塊的fork()方法生成。這意味著工作進程可以共享服務器句柄並使用IPC(進程間通信)與父Node進程通信。主進程負責啟動和控制工作進程。您可以在主進程中創建任意數量的工作進程。此外,請記住,默認情況下,傳入連接在工作進程之間以輪詢方式分配(Windows除外)。實際上,還有另一種分配傳入連接的方法,這裡我不會討論,它將分配交給操作系統(Windows中的默認設置)。 Node.js文檔建議使用默認的輪詢樣式作為調度策略。儘管從理論上講,使用集群模塊聽起來很複雜,但其實現非常簡單。要開始使用它,您必須將其包含在您的Node.js應用程序中:

var cluster = require('cluster');

集群模塊多次執行相同的Node.js進程。因此,您需要做的第一件事是確定哪一部分代碼用於主進程,哪一部分代碼用於工作進程。集群模塊允許您如下識別主進程:

if(cluster.isMaster) { ... }

主進程是您啟動的進程,它又會初始化工作進程。要在主進程中啟動工作進程,我們將使用fork()方法:

cluster.fork();

此方法返回一個worker對象,其中包含有關已派生的worker的一些方法和屬性。我們將在下一節中看到一些示例。集群模塊包含多個事件。與工作進程啟動和終止時刻相關的兩個常見事件是online和exit事件。當工作進程派生並發送online消息時,會發出online事件。當工作進程死亡時,會發出exit事件。稍後,我們將了解如何使用這兩個事件來控制工作進程的生命週期。現在,讓我們將到目前為止看到的所有內容放在一起,並展示一個完整的可運行示例。

示例

本節包含兩個示例。第一個示例是一個簡單的應用程序,顯示如何在Node.js應用程序中使用集群模塊。第二個示例是一個利用Node.js集群模塊的Express服務器,它是我通常在大規模項目中使用的生產代碼的一部分。這兩個示例都可以從GitHub下載。

如何在Node.js應用程序中使用集群模塊

在這個第一個示例中,我們設置了一個簡單的服務器,它使用包含處理請求的工作進程ID的消息來響應所有傳入請求。主進程派生四個工作進程。在每個工作進程中,我們開始監聽端口8000以接收傳入請求。實現我剛才描述的內容的代碼如下所示:

var cluster = require('cluster');
var http = require('http');
var numCPUs = 4;

if (cluster.isMaster) {
    for (var i = 0; i < numCPUs; i++) {
        cluster.fork();
    }
} else {
    http.createServer(function(req, res) {
        res.writeHead(200);
        res.end('process ' + process.pid + ' says hello!');
    }).listen(8000);
}

您可以通過啟動服務器(運行命令node simple.js)並訪問URL https://www.php.cn/link/7d2d180c45c41870f36e747816456190

如何開發高度可擴展的Express服務器

Express是Node.js最流行的Web應用程序框架之一(如果不是最流行的話)。在本網站上,我們已經多次介紹過它。如果您有興趣了解更多信息,我建議您閱讀文章《使用Express 4創建RESTful API》和《構建Node.js驅動的聊天室Web應用程序:Express和Azure》。第二個示例顯示瞭如何開發高度可擴展的Express服務器。它還演示瞭如何遷移單個進程服務器以利用少量代碼的集群模塊。

var cluster = require('cluster');

此示例的第一個補充是使用Node.js os模塊獲取CPU內核的數量。 os模塊包含一個cpus()函數,它返回一個CPU內核數組。使用這種方法,我們可以根據服務器規格動態確定要派生的工作進程數量,以最大限度地利用資源。第二個更重要的補充是處理工作進程的死亡。當工作進程死亡時,集群模塊會發出exit事件。可以通過偵聽該事件並在發出該事件時執行回調函數來處理它。您可以通過編寫類似cluster.on('exit', callback);的語句來做到這一點。在回調函數中,我們派生一個新的工作進程以保持預期的工作進程數量。這允許我們保持應用程序運行,即使有一些未處理的異常。在這個示例中,我還為online事件設置了一個偵聽器,每當派生工作進程並準備好接收傳入請求時,就會發出該事件。這可用於日誌記錄或其他操作。

性能比較

有幾種工具可以對API進行基準測試,但這裡我使用Apache Benchmark工具來分析使用集群模塊如何影響應用程序的性能。為了設置測試,我開發了一個Express服務器,它有一個路由和一個用於該路由的回調函數。在回調函數中,執行一個虛擬操作,然後返回一條簡短的消息。服務器有兩個版本:一個沒有工作進程,其中所有操作都在主進程中發生,另一個有8個工作進程(因為我的機器有8個內核)。下表顯示了合併集群模塊如何增加每秒處理的請求數。

并发连接 1 2 4 8 16
单进程 654 711 783 776 754
8个工作进程 594 1198 2110 3010 3024

(每秒處理的請求數)

高級操作

雖然使用集群模塊相對簡單,但您可以使用工作進程執行其他操作。例如,您可以使用集群模塊實現應用程序的(幾乎!)零停機時間。我們過一會兒將了解如何執行其中一些操作。

主進程和工作進程之間的通信

有時,您可能需要從主進程向工作進程發送消息以分配任務或執行其他操作。作為回報,工作進程可能需要通知主進程任務已完成。要偵聽消息,應在主進程和工作進程中都設置message事件的事件偵聽器:

var cluster = require('cluster');

worker對像是fork()方法返回的引用。要在工作進程中偵聽來自主進程的消息:

if(cluster.isMaster) { ... }

消息可以是字符串或JSON對象。要向特定工作進程發送消息,您可以編寫如下所示的代碼:

cluster.fork();

類似地,要向主進程發送消息,您可以編寫:

var cluster = require('cluster');
var http = require('http');
var numCPUs = 4;

if (cluster.isMaster) {
    for (var i = 0; i < numCPUs; i++) {
        cluster.fork();
    }
} else {
    http.createServer(function(req, res) {
        res.writeHead(200);
        res.end('process ' + process.pid + ' says hello!');
    }).listen(8000);
}

在Node.js中,消息是通用的,沒有特定類型。因此,最好將消息作為包含有關消息類型、發送者和內容本身的一些信息的JSON對象發送。例如:

var cluster = require('cluster');

if(cluster.isMaster) {
    var numWorkers = require('os').cpus().length;

    console.log('Master cluster setting up ' + numWorkers + ' workers...');

    for(var i = 0; i < numWorkers; i++) {
        cluster.fork();
    }

    cluster.on('online', function(worker) {
        console.log('Worker ' + worker.process.pid + ' is online');
    });

    cluster.on('exit', function(worker, code, signal) {
        console.log('Worker ' + worker.process.pid + ' died with code: ' + code + ', and signal: ' + signal);
        console.log('Starting a new worker');
        cluster.fork();
    });
} else {
    var app = require('express')();
    app.all('/*', function(req, res) {res.send('process ' + process.pid + ' says hello!').end();})

    var server = app.listen(8000, function() {
        console.log('Process ' + process.pid + ' is listening to all incoming requests');
    });
}

這裡需要注意的一點是,message事件回調是異步處理的。沒有定義的執行順序。您可以在GitHub上找到主進程和工作進程之間通信的完整示例。

零停機時間

使用工作進程可以實現的一個重要結果是(幾乎)零停機時間服務器。在主進程中,您可以在對應用程序進行更改後,一次一個地終止和重新啟動工作進程。這允許您在加載新版本的同時運行舊版本。為了能夠在運行時重新啟動應用程序,您需要記住兩點。首先,主進程一直運行,只有工作進程被終止和重新啟動。因此,重要的是要使主進程保持簡短,並且只負責管理工作進程。其次,您需要以某種方式通知主進程需要重新啟動工作進程。有幾種方法可以做到這一點,包括用戶輸入或監視文件更改。後者效率更高,但您需要在主進程中識別要監視的文件。我建議重新啟動工作進程的方法是首先嘗試安全地關閉它們;然後,如果它們沒有安全終止,則強制殺死它們。您可以通過向工作進程發送關閉消息來執行前者,如下所示:

worker.on('message', function(message) {
    console.log(message);
});

並在工作進程message事件處理程序中啟動安全關閉:

process.on('message', function(message) {
    console.log(message);
});

要對所有工作進程執行此操作,您可以使用集群模塊的workers屬性,該屬性保存對所有正在運行的工作進程的引用。我們還可以將所有任務包裝在主進程中的一個函數中,該函數可以在我們想要重新啟動所有工作進程時調用。

var cluster = require('cluster');

我們可以從集群模塊中的workers對象獲取所有正在運行的工作進程的ID。此對象保存對所有正在運行的工作進程的引用,並在終止和重新啟動工作進程時動態更新。首先,我們將所有正在運行的工作進程的ID存儲在workerIds數組中。這樣,我們避免重新啟動新派生的工作進程。然後,我們請求每個工作進程安全關閉。如果5秒後工作進程仍在運行並且仍然存在於workers對像中,那麼我們調用工作進程上的kill函數以強制其關閉。您可以在GitHub上找到一個實際示例。

結論

可以使用集群模塊對Node.js應用程序進行並行化,以便更有效地使用系統。可以使用幾行代碼同時運行多個進程,這使得遷移相對容易,因為Node.js處理困難的部分。正如我在性能比較中所展示的那樣,通過更有效地利用系統資源,應用程序性能有可能得到顯著提高。除了性能之外,您還可以通過在應用程序運行時重新啟動工作進程來提高應用程序的可靠性和正常運行時間。也就是說,在考慮在應用程序中使用集群模塊時,您需要注意。集群模塊的主要推薦用途是用於Web服務器。在其他情況下,您需要仔細研究如何在工作進程之間分配任務,以及如何在工作進程和主進程之間有效地溝通進度。即使對於Web服務器,在對應用程序進行任何更改之前,也要確保單個Node.js進程是瓶頸(內存或CPU),因為您的更改可能會引入錯誤。最後一點,Node.js網站為集群模塊提供了很好的文檔。因此,請務必查看一下!

關於Node.js集群的常見問題解答(FAQ)

使用Node.js集群的主要優勢是什麼?

使用Node.js集群的主要優勢是提高應用程序的性能。 Node.js在一個線程上運行,這意味著它一次只能利用一個CPU內核。但是,現代服務器通常有多個內核。通過使用Node.js集群,您可以創建一個主進程,該進程派生多個工作進程,每個工作進程都在不同的CPU內核上運行。這允許您的應用程序同時處理更多請求,從而顯著提高其速度和性能。

Node.js集群是如何工作的?

Node.js集群通過創建一個主進程來工作,該主進程派生多個工作進程。主進程偵聽傳入請求並將它們以輪詢方式分發給工作進程。每個工作進程都在單獨的CPU內核上運行並獨立處理請求。這允許您的應用程序利用所有可用的CPU內核並同時處理更多請求。

如何創建一個Node.js集群?

創建Node.js集群涉及使用Node.js提供的“cluster”模塊。首先,您需要導入“cluster”和“os”模塊。然後,您可以使用“cluster.fork()”方法來創建工作進程。 “os.cpus().length”為您提供可用的CPU內核數,您可以使用它來確定要創建的工作進程數。這是一個簡單的示例:

var cluster = require('cluster');

如何處理Node.js集群中的工作進程崩潰?

您可以通過偵聽主進程上的“exit”事件來處理Node.js集群中的工作進程崩潰。當工作進程崩潰時,它會向主進程發送“exit”事件。然後,您可以使用“cluster.fork()”方法來創建一個新的工作進程以替換崩潰的工作進程。這是一個示例:

if(cluster.isMaster) { ... }

我可以將Node.js集群與Express.js一起使用嗎?

是的,您可以將Node.js集群與Express.js一起使用。事實上,使用Node.js集群可以顯著提高Express.js應用程序的性能。您只需要將Express.js應用程序代碼放在集群腳本中的工作進程代碼塊中即可。

Node.js集群的局限性是什麼?

雖然Node.js集群可以顯著提高應用程序的性能,但它也有一些局限性。例如,工作進程不共享狀態或內存。這意味著您不能將會話數據存儲在內存中,因為它在所有工作進程中都不可訪問。相反,您需要使用共享會話存儲,例如數據庫或Redis服務器。

如何在Node.js集群中負載均衡請求?

默認情況下,Node.js集群中的主進程以輪詢方式將傳入請求分發給工作進程。這提供了一種基本的負載均衡形式。但是,如果您需要更高級的負載均衡,則可能需要使用反向代理服務器,例如Nginx。

我可以在生產環境中使用Node.js集群嗎?

是的,您可以在生產環境中使用Node.js集群。事實上,強烈建議在生產環境中使用Node.js集群,以充分利用服務器的CPU內核並提高應用程序的性能。

如何調試Node.js集群?

調試Node.js集群可能有點棘手,因為您有多個工作進程同時運行。但是,您可以對每個工作進程使用具有唯一端口的“inspect”標誌來將調試器附加到每個進程。這是一個示例:

cluster.fork();

我可以將Node.js集群與其他Node.js模塊一起使用嗎?

是的,您可以將Node.js集群與其他Node.js模塊一起使用。但是,您需要注意的是,工作進程不共享狀態或內存。這意味著如果模塊依賴於共享狀態,它可能無法在集群環境中正常工作。

以上是如何創建一個node.js群集以加速您的應用的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
Python vs. JavaScript:學習曲線和易用性Python vs. JavaScript:學習曲線和易用性Apr 16, 2025 am 12:12 AM

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

Python vs. JavaScript:社區,圖書館和資源Python vs. JavaScript:社區,圖書館和資源Apr 15, 2025 am 12:16 AM

Python和JavaScript在社區、庫和資源方面的對比各有優劣。 1)Python社區友好,適合初學者,但前端開發資源不如JavaScript豐富。 2)Python在數據科學和機器學習庫方面強大,JavaScript則在前端開發庫和框架上更勝一籌。 3)兩者的學習資源都豐富,但Python適合從官方文檔開始,JavaScript則以MDNWebDocs為佳。選擇應基於項目需求和個人興趣。

從C/C到JavaScript:所有工作方式從C/C到JavaScript:所有工作方式Apr 14, 2025 am 12:05 AM

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。

JavaScript引擎:比較實施JavaScript引擎:比較實施Apr 13, 2025 am 12:05 AM

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

超越瀏覽器:現實世界中的JavaScript超越瀏覽器:現實世界中的JavaScriptApr 12, 2025 am 12:06 AM

JavaScript在現實世界中的應用包括服務器端編程、移動應用開發和物聯網控制:1.通過Node.js實現服務器端編程,適用於高並發請求處理。 2.通過ReactNative進行移動應用開發,支持跨平台部署。 3.通過Johnny-Five庫用於物聯網設備控制,適用於硬件交互。

使用Next.js(後端集成)構建多租戶SaaS應用程序使用Next.js(後端集成)構建多租戶SaaS應用程序Apr 11, 2025 am 08:23 AM

我使用您的日常技術工具構建了功能性的多租戶SaaS應用程序(一個Edtech應用程序),您可以做同樣的事情。 首先,什麼是多租戶SaaS應用程序? 多租戶SaaS應用程序可讓您從唱歌中為多個客戶提供服務

如何使用Next.js(前端集成)構建多租戶SaaS應用程序如何使用Next.js(前端集成)構建多租戶SaaS應用程序Apr 11, 2025 am 08:22 AM

本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫

JavaScript:探索網絡語言的多功能性JavaScript:探索網絡語言的多功能性Apr 11, 2025 am 12:01 AM

JavaScript是現代Web開發的核心語言,因其多樣性和靈活性而廣泛應用。 1)前端開發:通過DOM操作和現代框架(如React、Vue.js、Angular)構建動態網頁和單頁面應用。 2)服務器端開發:Node.js利用非阻塞I/O模型處理高並發和實時應用。 3)移動和桌面應用開發:通過ReactNative和Electron實現跨平台開發,提高開發效率。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
1 個月前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它們
1 個月前By尊渡假赌尊渡假赌尊渡假赌

熱工具

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器