求教大神一个Nodejs express+cluster的问题

求教大神一个Nodejs express+cluster的问题

master.js代码: QQ图片20141111154145.jpg http模块代码: QQ图片20141111154220.jpg Express代码: QQ图片20141111154241.jpg

如果用原生的http模块,每次请求进程分配处理正常 换express后只有一个进程会处理请求,不知道是什么原因???求指教


4 回复

根据您的描述,您正在使用 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端口`);
}

解释

  1. master.js:

    • 使用cluster.isMaster判断当前是否为主进程。
    • 如果是主进程,则根据可用的CPU核心数量创建相同数量的工作进程。
    • 每个工作进程都会独立启动一个Express应用并监听指定端口(在这个例子中为3000)。
  2. 工作进程:

    • 各个工作进程启动独立的Express应用,并监听同一个端口。
    • 这样可以确保请求被均匀地分发到不同的工作进程中。

通过这种方式,你可以确保Express应用能够充分利用多核CPU的优势,避免出现只有单一进程处理请求的情况。如果你仍然遇到问题,请检查是否有其他配置或中间件干扰了请求的分发。

回到顶部