使用例子
为了让node应用能够在多核服务器中提高性能,node提供cluster API,用于创建多个工作进程,然后由这些工作进程并行处理请求。
// master.js
const cluster = require('cluster');
const cpusLen = require('os').cpus().length;
const path = require('path');
console.log(`主进程:${
process.pid}`);
cluster.setupMaster({
exec: path.resolve(__dirname, './work.js'),
});
for (let i = 0; i < cpusLen; i++) {
cluster.fork();
}
// work.js
const http = require('http');
console.log(`工作进程:${
process.pid}`);
http.createServer((req, res) => {
res.end('hello');
}).listen(8080);
上面例子中,使用cluster创建多个工作进程,这些工作进程能够共用8080端口,我们请求localhost:8080,请求任务会交给其中一个工作进程进行处理,该工作进程处理完成后,自行响应请求。
端口占用问题
这里有个问题,前面例子中,出现多个进程监听相同的端口,为什么程序没有报端口占用问题,由于socket套接字监听端口会有一个文件描述符,而每个进程的文件描述符都不相同,无法让多个进程都监听同一个端口,如下:
// master.js
const fork = require('child_process').fork;
const cpusLen = require('os').cpus().length;
const path = require('path');
console.log(`主进程:${
process.pid}`);
for (let i = 0; i < cpusLen; i++) {
fork(path.resolve(__dirname, './work.js'));
}
// work.js
const http = require('http');
console.log(`工作进程:${
process.pid}`);
http.createServer((req, res) => {
res.end('hello');
}).listen(8080);
当运行master.js文件的时候,会报端口被占用的问题(Error: listen EADDRINUSE: address already in use :::8080)。
我们修改下,只使用主进程监听端口,主进程将请求套接字发放给工作进程,由工作进程来进行业务处理。
// master.js
const fork = require('child_process').fork;
const cpusLen = require('os').cpus().length;
const path = require('path');
const net = require('net');
const server = net.createServer();
console.log(`主进程:${
process.pid}`);
const works = [];
let current = 0
for (let i = 0; i < cpusLen; i++) {
works.push(fork(path.resolve(__dirname, './work.js')));
}
server.listen(8080, () => {
if (current > works.length - 1) current = 0
works[current++].send('server', server);
server.close();
});
// work.js
const http = require('http');
const server = http.createServer((req, res) => {
res.end

本文详细介绍了Node.js的cluster模块,用于在多核服务器中创建进程以提高性能。主要内容包括工作进程如何共享端口、如何处理端口占用问题以及源码解读,揭示了主进程如何监听端口并分配请求给工作进程,从而避免端口冲突。
最低0.47元/天 解锁文章
9206

被折叠的 条评论
为什么被折叠?



