求教大神一个Nodejs express+cluster的问题
求教大神一个Nodejs express+cluster的问题
master.js代码:
http模块代码:
Express代码:
如果用原生的http模块,每次请求进程分配处理正常 换express后只有一个进程会处理请求,不知道是什么原因???求指教
根据您的描述,您正在使用 Node.js 的 express
框架结合 cluster
模块来实现多进程处理。然而,在使用 Express 框架时,发现只有单个进程在处理请求,而您希望所有工作进程都能分担请求负载。
原因分析
当使用 cluster
模块时,主进程(master)创建多个工作进程(workers),每个工作进程都有自己的监听端口。但在 Express 中,我们通常只在一个工作进程中启动服务器。因此,其他工作进程可能没有正确地接收和处理请求。
解决方案
为了解决这个问题,我们需要确保每个工作进程都启动一个独立的 Express 服务器实例,并监听不同的端口。我们可以利用 cluster
模块中的 isWorker
属性来判断当前进程是否为工作进程,并在此基础上启动 Express 服务器。
示例代码
master.js (主进程)
const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
console.log(`Master process running on PID: ${process.pid}`);
// 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 {
// Worker processes run this code
require('./worker.js');
}
worker.js (工作进程)
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.send('Hello from Worker ' + process.pid);
});
// 获取当前工作进程的唯一端口号
const port = 8000 + process.pid % 1000;
app.listen(port, () => {
console.log(`Worker ${process.pid} listening on port ${port}`);
});
关键点解释
- 主进程:主进程负责创建工作进程,并监听工作进程的退出事件。
- 工作进程:每个工作进程都会启动一个独立的 Express 服务器实例,并监听不同的端口。
- 端口分配:为了简化,这里通过简单的数学运算分配端口,确保每个进程使用不同的端口,避免端口冲突。
通过这种方式,您可以确保每个工作进程都能够独立地处理请求,从而实现负载均衡。
我把Express的代码补充完整试了下,感觉没什么问题啊。
var express = require('express'),
http = require('http');
var app = express();
app.get(’/’,function(req,res){
console.log('request on ’ + process.pid);
res.send(‘Hello World’);
})
var server = http.createServer(app);
console.log('webserver started on ’ + process.pid);
process.on(‘message’,function(msg,socket){
process.nextTick(function(){
if(msg == ‘c’ && socket) {
socket.readable = socket.writable = true;
socket.resume();
server.connections++;
socket.server = server;
server.emit(‘connection’,socket);
socket.emit(‘connect’);
}
})
})
我用curl测了下,新的请求都是新的进程处理,没问题的。
我是win7…
根据你的描述,问题可能是由于Express应用在使用cluster
模块时没有正确地分发请求到各个工作进程。以下是一个简单的例子来说明如何使用cluster
模块与Express配合工作。
示例代码
master.js
const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
console.log(`主进程 ${process.pid} 正在运行`);
// 根据CPU核心数量创建子进程
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
// 监听所有子进程的退出事件
cluster.on('exit', (worker, code, signal) => {
console.log(`工作进程 ${worker.process.pid} 已退出`);
});
} else {
// 子进程启动Express应用
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.listen(3000);
console.log(`工作进程 ${process.pid} 正在监听3000端口`);
}
解释
-
master.js:
- 使用
cluster.isMaster
判断当前是否为主进程。 - 如果是主进程,则根据可用的CPU核心数量创建相同数量的工作进程。
- 每个工作进程都会独立启动一个Express应用并监听指定端口(在这个例子中为3000)。
- 使用
-
工作进程:
- 各个工作进程启动独立的Express应用,并监听同一个端口。
- 这样可以确保请求被均匀地分发到不同的工作进程中。
通过这种方式,你可以确保Express应用能够充分利用多核CPU的优势,避免出现只有单一进程处理请求的情况。如果你仍然遇到问题,请检查是否有其他配置或中间件干扰了请求的分发。