Node.js使用多进程提高任务执行效率

 更新时间:2022年09月24日 09:41:45   作者:代码与野兽  
在Node.JS中使用多进程非常简单,合理使用多进程,可以解放硬件的能力,让软件的运行效率得到肉眼可见的提升。本文详细讲解了Node.js使用多进程提高任务执行效率的方法,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

最近我有个学员写了个 Node.js 脚本程序,定时从某个服务器下载文件,并向另一个云服务商上传文件。

但是每次只能先下载一个文件,再去上传一个文件。效率比较低。于是他向我请教,怎么样才能提高效率?我告诉他应该用 Node 的多进程技术。

什么是 Node 多进程?

Node 是在单个线程中运行,我们虽然没办法开启额外的线程,但是可以开启进程集群。这样可以让下载任务和上传任务同时进行。

使用多进程进行初步代码优化

简单看了一下学员的代码,大概是这样:

const dl = require('./download.js')
const ul = require('./upload.js')
const source = require('./source.js')

async function runTask() {
  const { originUrl, targetUrl } = source.getNext()
  const { data } = await dl(originUrl)
  await ul(targetUrl, data)
  runTask()
}

runTask()

这个代码逻辑上是没问题的,但是它只能在 1 个 CPU 核心中运行。

我们完全可以使用 Node.js 的多进程来利用 CPU 的多核心来增加这个程序的吞吐量。

怎么改造呢?

也非常简单。

const os = require('os')
const cluster = require('cluster')
const dl = require('./download.js')
const ul = require('./upload.js')
const source = require('./source.js')

function run() {
  if(cluster.isMaster) {
    const numCPUs = os.cpus().length;
    for(let idx = 0; idx < numCPUs; idx++) {
      cluster.fork();
    }
  } else {
    runTask()
  }
}

async function runTask() {
    const { originUrl, targetUrl } = source.getNext()
    const { data } = await dl(originUrl)
    await ul(targetUrl, data)
    runTask()
  }
}

run()

在上面的代码中,我添加了 os 和 cluster 模块。os 模块可以告诉我们运行环境的 CPU 信息,我们可以通过它来做为创建进程数量的限制条件。然后通过 cluster.isMaster 来判断是否是主进程,因为只有主进程才拥有 fork 的能力。

worker和master通信

其实上面的代码还可以继续做更深层次的优化,仔细分析一下,下载速度和上传速度其实是不一致的。通常来说,下载速度会很慢,但上传速度会很快。我们可以让其他进程去下载文件,当下载成功之后,让主进程去上传文件。

Node 中的多进程之间不会共享内存,所以我们可以通过消息传递的方式,让下载进程通知主进程去上传文件。

const os = require('os')
const cluster = require('cluster')
const dl = require('./download.js')
const ul = require('./upload.js')
const source = require('./source.js')

function run() {
  if(cluster.isMaster) {
    const numCPUs = os.cpus().length;
    for(let idx = 0; idx < numCPUs; idx++) {
      const worker = cluster.fork();
      worker.on('message', ({ targetUrl, data }) => {
        ul(targetUrl, data)
      })
    }
  } else {
    runTask()
  }
}

async function runTask() {
  const { originUrl, targetUrl } = source.getNext()
  const { data } = await dl(originUrl)
  process.send({ targetUrl, data })
  runTask()
}

run()

可以在主进程中通过 worker.on('message', (msg)=>{}) 的方式来监听子进程发送的消息。在子进程中通过 process.send 来向主进程发送消息。

总结

在 NodeJS 中使用多进程非常简单,合理使用多进程,可以解放硬件的能力,让软件的运行效率得到肉眼可见的提升。

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。如果你想了解更多相关内容请查看下面相关链接

相关文章

  • node.js版本管理工具n无效的原理和解决方法

    node.js版本管理工具n无效的原理和解决方法

    大家都知道在Centos中一般需要根据项目的环境安装指定版本的Node, 而现有的yum源版本一般不够全面也不一定找的到所需要的指定版本, 此时就必须自行下载Node源码进行编译安装了,如果你在使用node.js版本管理工具n的时候发现工具无效,下面就来看看这篇文章的解决方法吧。
    2016-11-11
  • node.js中的http.response.addTrailers方法使用说明

    node.js中的http.response.addTrailers方法使用说明

    这篇文章主要介绍了node.js中的http.response.addTrailers方法使用说明,本文介绍了http.response.addTrailers的方法说明、语法、接收参数、使用实例和实现源码,需要的朋友可以参考下
    2014-12-12
  • nodejs aes 加解密实例

    nodejs aes 加解密实例

    今天小编就为大家分享一篇nodejs aes 加解密实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-10-10
  • 基于node的tcp客户端和服务端的简单通信

    基于node的tcp客户端和服务端的简单通信

    通过Nodejs,我们可以快速地搭建一个简单的Web服务器,实现服务端与客户端的简单通信,本文主要介绍了基于node的tcp客户端和服务端的简单通信,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • nodejs简单实现操作arduino

    nodejs简单实现操作arduino

    本文给大家分享的是使用nodejs来驱动arduino,主要是基于cylonjs 和 gort,有需要的小伙伴可以参考下
    2016-09-09
  • npm does not support Node.js问题的解决办法

    npm does not support Node.js问题的解决办法

    这篇文章主要给大家介绍了关于npm does not support Node.js问题的解决办法,文中通过代码以及图文介绍的非常详细,对大家的学习或者工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-10-10
  • Node.js 连接 MySql 统计组件属性的使用情况解析

    Node.js 连接 MySql 统计组件属性的使用情况解析

    这篇文章主要为大家介绍了Node.js 连接 MySql 统计组件属性的使用情况解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-10-10
  • nvm管理node无法正常切换node版本问题的解决方法

    nvm管理node无法正常切换node版本问题的解决方法

    相信一定会有存在一些小伙伴 明明都已经按着操作卸载node 和安装nvm 了但是 依旧无法正常通过nvm管理node,本文将给大家介绍nvm管理node无法正常切换node版本问题的解决方法,需要的朋友可以参考下
    2024-01-01
  • nodejs 全局变量和全局对象知识点及用法详解

    nodejs 全局变量和全局对象知识点及用法详解

    在本篇文章里小编给大家整理的是一篇关于nodejs 全局变量和全局对象知识点及用法等内容,对此有兴趣的朋友们可以学习参考下。
    2021-12-12
  • Nodejs实战心得之eventproxy模块控制并发

    Nodejs实战心得之eventproxy模块控制并发

    本篇文章给大家分享我的nodejs实战心得,如何使用eventproxy模块控制并发,感兴趣的朋友可以参考下
    2015-10-10

最新评论