增加Nodejs进程数为什么效率不升反降?

增加Nodejs进程数为什么效率不升反降?

场景: node向某服务器发请求,每次发5000个请求,等待这5000个处理完后,再发5000,如此循环进行.机器配置8个cpu核

现象: 当我开启一个node程序时,该程序的cpu使用率能达到90-100% ,并且每分钟能发27万左右的请求。 但是当我开两个node 程序时,每个node的cpu使用率只有60%, 并且每分钟一共可发4万请求。

太诡异了,在系统负载还很小的情况下,再增一个node,不是把效率翻倍吗? who can tell me why?

代码如下: var http=require(‘http’) var logger=require(’./log’).clientLogger var options = { port: 3000, path: ‘/info?n=1&m=2’, method: ‘GET’, host:‘db11’ };

count=6000

function main(allcount){

for(var i=0;i<count;i++){ var req = http.request(options, function(res) { res.setEncoding(‘utf8’); res.on(‘data’, function (chunk) { logger.debug('BODY: ’ + chunk); if(!–allcount) { main(count) } }); });

req.on(‘error’, function(e) { logger.error('problem with request: ’ + e.message); if(!–allcount) { main(count) } });

req.end(); logger.info(‘send a request’) } }

main(count)

setInterval(function(){process.exit(0)},5601000)


12 回复

增加Node.js 进程数为什么效率不升反降?

场景描述

假设你有一个 Node.js 应用程序,它需要向某个服务器发送大量请求。每次发送 5000 个请求,并等待这些请求处理完毕后再继续发送下一批 5000 个请求。你的机器配置为 8 个 CPU 核心。

观察到的现象

当你运行一个 Node.js 程序时,CPU 使用率可以达到 90%-100%,并且每分钟可以发送大约 27 万个请求。然而,当你启动两个这样的 Node.js 程序时,每个程序的 CPU 使用率下降到约 60%,而且两个程序一起只能每分钟发送大约 4 万个请求。

问题分析

在多进程环境下,每个进程都会争夺 CPU 资源。虽然理论上增加进程数量可以提高并发处理能力,但实际上会遇到一些限制,比如上下文切换、内存管理等开销,导致整体效率反而下降。

代码示例

以下是你的代码示例:

const http = require('http');
const logger = require('./log').clientLogger;

const options = {
    port: 3000,
    path: '/info?n=1&m=2',
    method: 'GET',
    host: 'db11'
};

let count = 6000;

function main(allcount) {
    for (let i = 0; i < allcount; i++) {
        const req = http.request(options, function (res) {
            res.setEncoding('utf8');
            res.on('data', function (chunk) {
                logger.debug('BODY: ' + chunk);
                if (!--allcount) {
                    main(count);
                }
            });
        });

        req.on('error', function (e) {
            logger.error('problem with request: ' + e.message);
            if (!--allcount) {
                main(count);
            }
        });

        req.end();
        logger.info('send a request');
    }
}

main(count);

setInterval(function () { process.exit(0); }, 5 * 60 * 1000);

解释

  1. 上下文切换:当多个进程同时运行时,操作系统需要频繁地进行上下文切换,这会导致额外的开销。
  2. 资源竞争:多个进程共享相同的资源(如网络连接、文件描述符等),可能会导致资源争用,从而降低性能。
  3. 内存管理:每个进程都需要一定的内存空间,多个进程同时运行会占用更多的内存,可能导致内存碎片化等问题。
  4. I/O 阻塞:Node.js 是单线程的,尽管它使用事件循环来处理 I/O 操作,但在高并发情况下,I/O 操作仍然可能成为瓶颈。

改进建议

为了提高性能,你可以考虑以下几种方法:

  1. 使用线程池:利用 worker_threads 模块创建线程池,而不是直接创建多个进程。
  2. 异步 I/O:确保所有 I/O 操作都是非阻塞的,以充分利用 Node.js 的事件循环机制。
  3. 优化代码逻辑:减少不必要的循环和递归调用,避免重复的资源请求。

通过这些改进,你可以更有效地利用系统资源,提高应用程序的整体性能。


贴相关的 node.js 端代码上来看看。

上代码……

好的

nodejs 是运行时候的多线程,当你增加node个数时对应的线程就多了,CPU就会忙于切换照成性能降低。

如果不是多核,增加进程肯定会降低效率,就像楼上所说的那样。

你管这个叫多进程??

I服了U……

 var mCluster = require('cluster');
 ....
 
  for ( var index = 0; index < mCpuCount; index++) {

  var tWorker = mCluster.fork();

  tWorker.on('message', function(m,aSocket) {

没有理解进程集群的概念

在Node.js中,增加进程数量并不一定能提高整体性能,甚至可能会导致效率下降。这是因为Node.js本身是单线程的事件驱动模型,它依赖于异步I/O操作来实现高并发。当你增加进程数量时,操作系统需要在进程之间进行调度,这会带来额外的开销。

以下是一些可能导致效率下降的原因:

  1. 进程间通信开销:多个进程之间的通信和数据交换会产生额外的开销。
  2. 资源竞争:多个进程同时运行可能会导致对CPU、内存等资源的竞争,从而影响整体性能。
  3. 操作系统调度开销:操作系统需要管理多个进程,增加了调度开销。

示例代码优化

你可以尝试使用cluster模块来创建多个工作进程,而不是直接启动多个Node.js实例。cluster模块可以帮助你在多核CPU上更有效地利用资源。

const cluster = require('cluster');
const os = require('os');

const COUNT = 6000;

if (cluster.isMaster) {
    const numCPUs = os.cpus().length;
    for (let i = 0; i < numCPUs; i++) {
        cluster.fork();
    }
} else {
    const http = require('http');
    const logger = require('./log').clientLogger;
    const options = {
        port: 3000,
        path: '/info?n=1&m=2',
        method: 'GET',
        host: 'db11'
    };

    function main(allcount) {
        for (let i = 0; i < COUNT; i++) {
            const req = http.request(options, (res) => {
                res.setEncoding('utf8');
                res.on('data', (chunk) => {
                    logger.debug('BODY: ' + chunk);
                    if (!--allcount) {
                        main(COUNT);
                    }
                });
            });

            req.on('error', (e) => {
                logger.error('problem with request: ' + e.message);
                if (!--allcount) {
                    main(COUNT);
                }
            });

            req.end();
            logger.info('send a request');
        }
    }

    main(COUNT);

    setInterval(() => process.exit(0), 5 * 60 * 1000);
}

解释

  1. 主进程(Master):主进程负责创建与CPU核心数量相匹配的工作进程。
  2. 工作进程(Worker):每个工作进程执行相同的任务逻辑。

通过这种方式,可以更好地利用多核CPU的优势,减少进程间通信的开销,并提高整体性能。

回到顶部