集群原理
Node.js 的集群原理是基於其非阻塞 I/O 與事件驅動的特性,並通過 cluster
模組來達到多程序的運行。以下是 Node.js 集群的基本原理和概念:
單程序的局限:Node.js 預設運行在單一程序上,這意味著只能利用一個 CPU 核心。在多核心的硬體環境中,這顯然是不充分和效率低下的。
cluster 模組:Node.js 提供了一個名為
cluster
的核心模組,允許設置多個子程序(工作程序)。這些子程序可以共享同一個 TCP/IP 端口並且在主程序下運行,使得應用可以利用所有的 CPU 核心。Master 和 Worker:
- Master 程序:負責均衡負載、創建 Worker 程序和監控 Worker 程序。當 Worker 程序結束後,Master 程序可以再次創建一個新的 Worker 程序來替換它。
- Worker 程序:執行實際的應用程式代碼。在多數情況下,Worker 程序是應用的主要運行部分,而 Master 程序主要作為系統調度和管理。
負載均衡:Node.js 的 cluster 模組使用了操作系統層級的負載均衡來分配外來的連接到各個工作程序。在 Linux 下,它使用了 round-robin 方法,但在其他平台和某些情況下,它可能只是將所有連接分發到最先創建的工作程序。
IPC 通信:Master 與 Worker 之間存在一個 IPC (Inter-process communication) 通道,使得他們之間可以互相發送消息。這在某些需要主程序與工作程序間通信的場景中非常有用。
使用 Node.js 的集群功能可以大大提高伺服器的性能和容錯能力,特別是在多核 CPU 的環境下。然而,它也引入了更多的複雜性,例如應對工作程序崩潰、狀態共享問題等。
IPC 通信實作
IPC 通信代表 "Inter-Process Communication",是指兩個或多個程序之間傳遞數據或信號的機制。程序間通信允許程序彼此協作,並確保它們可以正確、有效地共享資源或交換信息。在多任務作業系統中,這是一個非常重要的功能。
創建兩個文件: parent.js 和 child.js。
child.js:
process.on('message', (message) => {
console.log('接收到消息:', message);
if (message === '你好, 子程序!') {
process.send('你好, 主程序!');
}
});
parent.js:
const { fork } = require('child_process');
const child = fork('./child.js');
child.on('message', (message) => {
console.log('接收到消息:', message);
});
child.send('你好, 子程序!');
執行:
node parent.js
結果:
接收到消息: 你好, 主進程!
集群原理實作
Master 程序:在專用主程序裡監聽請求
Worker 程序:創建 server 並監聽。通過 IPC 通信,向 Master 程序發送消息,讓 Master 程序也創建 server 並監聽,共同監聽同一個端口。
const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
console.log('Master ${process.pid} is running');
// Fork workers.
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
console.log('worker ${worker.process.pid} died');
});
} else {
http.createServer((req, res) => {
res.writeHead(200);
res.end('hello world\n');
}).listen(8000);
console.log('Worker ${process.pid} started');
}