Node.js使用多進(jìn)程提高任務(wù)執(zhí)行效率
最近我有個學(xué)員寫了個 Node.js 腳本程序,定時從某個服務(wù)器下載文件,并向另一個云服務(wù)商上傳文件。
但是每次只能先下載一個文件,再去上傳一個文件。效率比較低。于是他向我請教,怎么樣才能提高效率?我告訴他應(yīng)該用 Node 的多進(jìn)程技術(shù)。
什么是 Node 多進(jìn)程?
Node 是在單個線程中運(yùn)行,我們雖然沒辦法開啟額外的線程,但是可以開啟進(jìn)程集群。這樣可以讓下載任務(wù)和上傳任務(wù)同時進(jìn)行。
使用多進(jìn)程進(jìn)行初步代碼優(yōu)化
簡單看了一下學(xué)員的代碼,大概是這樣:
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 核心中運(yùn)行。
我們完全可以使用 Node.js 的多進(jìn)程來利用 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 模塊可以告訴我們運(yùn)行環(huán)境的 CPU 信息,我們可以通過它來做為創(chuàng)建進(jìn)程數(shù)量的限制條件。然后通過 cluster.isMaster 來判斷是否是主進(jìn)程,因為只有主進(jìn)程才擁有 fork 的能力。
worker和master通信
其實上面的代碼還可以繼續(xù)做更深層次的優(yōu)化,仔細(xì)分析一下,下載速度和上傳速度其實是不一致的。通常來說,下載速度會很慢,但上傳速度會很快。我們可以讓其他進(jìn)程去下載文件,當(dāng)下載成功之后,讓主進(jìn)程去上傳文件。
Node 中的多進(jìn)程之間不會共享內(nèi)存,所以我們可以通過消息傳遞的方式,讓下載進(jìn)程通知主進(jìn)程去上傳文件。
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()
可以在主進(jìn)程中通過 worker.on('message', (msg)=>{}) 的方式來監(jiān)聽子進(jìn)程發(fā)送的消息。在子進(jìn)程中通過 process.send 來向主進(jìn)程發(fā)送消息。
總結(jié)
在 NodeJS 中使用多進(jìn)程非常簡單,合理使用多進(jìn)程,可以解放硬件的能力,讓軟件的運(yùn)行效率得到肉眼可見的提升。
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,謝謝大家對腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請查看下面相關(guān)鏈接
相關(guān)文章
Node.js+Express+Mysql 實現(xiàn)增刪改查
這篇文章主要介紹了Node.js+Express+Mysql 實現(xiàn)增刪改查,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04Node Express用法詳解【安裝、使用、路由、中間件、模板引擎等】
這篇文章主要介紹了Node Express用法,結(jié)合實例形式詳細(xì)分析了node.js Express安裝、使用、路由、中間件、模板引擎等相關(guān)概念、原理及操作注意事項,需要的朋友可以參考下2020-05-05Node.js中Bootstrap-table的兩種分頁的實現(xiàn)方法
這篇文章主要介紹了Node.js中Bootstrap-table的兩種分頁的使用方法,需要的朋友可以參考下2017-09-09Nodejs把接收圖片base64格式保存為文件存儲到服務(wù)器上
這篇文章主要介紹了Nodejs把接收圖片base64格式保存為文件存儲到服務(wù)器上,文中代碼較簡短,需要的朋友可以參考下2018-09-09nodejs16.15.0版本如何解決node-sass和sass-loader版本沖突問題
這篇文章主要介紹了nodejs16.15.0版本如何解決node-sass和sass-loader版本沖突問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-08-08Node.js基于node-schedule實現(xiàn)定時任務(wù)的操作步驟
實際工作中,可能會遇到定時清除某個文件夾內(nèi)容,定時發(fā)送消息或發(fā)送郵件給指定用戶,定時導(dǎo)出某些數(shù)據(jù)等,node-schedule是一個非常不錯的npm包,可以幫助我們快速的創(chuàng)建和管理定時任務(wù),所以本文介紹了Node.js基于node-schedule實現(xiàn)定時任務(wù)的操作步驟,需要的朋友可以參考下2024-09-09nodejs使用PassThrough流進(jìn)行數(shù)據(jù)傳遞合并示例詳解
這篇文章主要為大家介紹了nodejs使用PassThrough流進(jìn)行數(shù)據(jù)傳遞合并示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09