新手请教一个Nodejs cluster+http.request的问题?

新手请教一个Nodejs cluster+http.request的问题?

想做一个压测工具,比方说在一个简单代码中实现: http.get(“http://www.sohu.com”, function(res) { console.log("Got response: " + res.statusCode); }); 是可以运行OK的? 不知道为什么同样的代码在cluster中运行会有没有任何反应呢?是因为执行太快直接EXIT了吗? 请前辈们帮忙指点一下:

cluster的部分代码:

console.time(‘cluster’); if (cluster.isMaster) { for (var i= 0;i<numCPUs;i++) { cluster.fork(); } var i=numCPUs; cluster.on(‘exit’,function(worker,code,signal){ if (!–i) { console.timeEnd(‘cluster’); process.exit(0); }

});

} else { //console.log(fibo(40)); http.get(“http://www.sohu.com”, function(res) { console.log("Got response: " + res.statusCode); }); // console.log(cluster.worker.id +’:’ +testio()); process.exit(0); }


4 回复

当然可以。根据你提供的信息,你在使用 Node.js 的 cluster 模块来创建多进程,并且尝试使用 http.get 来进行 HTTP 请求。然而,在集群模式下,请求可能没有预期的行为。以下是一些可能的原因及解决方案。

问题分析

  1. 进程退出:在你的代码中,每个工作进程(worker)在执行完 http.get 请求后立即调用 process.exit(0)。这会导致进程在完成请求之前就退出。
  2. 异步操作http.get 是一个异步操作,如果你立即退出进程,请求可能不会得到正确处理。

解决方案

你可以通过延迟 process.exit 或者确保所有请求都完成后再退出进程。以下是修改后的代码示例:

const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;

console.time('cluster');

if (cluster.isMaster) {
    for (let i = 0; i < numCPUs; i++) {
        cluster.fork();
    }

    let i = numCPUs;
    cluster.on('exit', function(worker, code, signal) {
        if (--i === 0) {
            console.timeEnd('cluster');
            process.exit(0);
        }
    });
} else {
    // 在这里执行你的 http.get 请求
    http.get("http://www.sohu.com", function(res) {
        console.log(`Worker ${cluster.worker.id}: Got response: ${res.statusCode}`);
    }).on('error', function(e) {
        console.error(`Worker ${cluster.worker.id}: Got error: ${e.message}`);
    });

    // 确保进程不会立即退出
    setTimeout(() => {
        process.exit(0);
    }, 5000);  // 延迟5秒确保请求有足够的时间完成
}

关键点解释

  1. 延迟退出:在工作进程中,我们使用 setTimeout 延迟 process.exit 的调用,确保请求有足够的时间完成。
  2. 错误处理:在 http.get 请求中添加了错误处理,以捕获任何潜在的错误。
  3. 日志记录:在日志记录中添加了 cluster.worker.id,以便区分不同工作进程的日志输出。

这样,你的压测工具应该可以在集群模式下正常运行并记录 HTTP 请求的结果。


标准输出流没有跟主进程用同一个吧

大哥,这句话怎么理解?是要worker向process传参数吗?

在这个问题中,你想要在Node.js的cluster模式下使用http.get来发起HTTP请求。问题在于,在子进程中立即调用process.exit(0)会导致进程在HTTP请求完成之前退出。

以下是一个改进后的示例代码,展示了如何在每个子进程中正确地处理HTTP请求,并在请求完成后退出子进程:

const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
    console.time('cluster');
    
    for (let i = 0; i < numCPUs; i++) {
        cluster.fork();
    }

    let remainingWorkers = numCPUs;

    cluster.on('exit', worker => {
        if (--remainingWorkers === 0) {
            console.timeEnd('cluster');
            process.exit(0);
        }
    });
} else {
    http.get("http://www.sohu.com", res => {
        console.log(`Worker ${cluster.worker.id}: Got response: ${res.statusCode}`);
        // 当HTTP请求完成时,退出子进程
        process.exit(0);
    }).on('error', err => {
        console.error(`Worker ${cluster.worker.id}: Error: ${err.message}`);
        process.exit(1);
    });
}

在这段代码中,我们在子进程中启动了一个HTTP GET请求,并在请求完成后或发生错误时退出子进程。主进程会等待所有子进程都完成后再结束自身。这样可以确保所有子进程都能正常处理HTTP请求并退出。

回到顶部