[英]Limit the number of concurrent child processes spawned in a loop in Node.js
[英]How can I limit the number of child processes in imagemin-mozjpeg?
我正在使用使用mozjpeg二進制文件壓縮圖像的imagemin-mozjpeg。
問題是我在Node.js Web服務器中使用它。
現在是這樣的:
我正在使用“請求”模塊(fs.createReadStream)上傳JPEG圖像。
Multer處理流並將其保留在緩沖區(內存存儲)中。
然后將緩沖區傳遞給imagemin進行壓縮。
然后將壓縮的緩沖區寫入文件。 (example.jpg)
一切正常。
這里的問題是,對於每個請求,都會生成一個新的mozjpeg二進制子進程cjpeg。
1個子進程占用12.5 MB的內存(.5 MB文件)。
如果我同時有50個請求,那將達到〜700 MB,因為對於50張圖像,有50個子進程。
有什么辦法可以限制子進程的數量? (該庫正在使用“ execa”模塊)或只是生成4-5個子進程,它們會對所有請求進行壓縮。
謝謝
if (req.files.myimage[0].buffer) {
let fileNumber = filesUploaded++;
imagemin.buffer(req.files.myimage[0].buffer, {
plugins: [
imageminMozjpeg({ quality: 60, progressive: true })
]
})
.then(file => {
fs.writeFile(__dirname + '/uploads/' + uuidv4() + '.jpg', file, 'hex' , function () {
res.end("SUCCESS" + fileNumber.toString());
});
})
.catch(err => {
console.log(err);
res.end("FAILED");
});
}
解決此問題的主要概念是將調用次數限制為imagemin()
(產生圖像處理過程的調用)。
也許您可以使用任務隊列來實現一個任務調度系統,以收集請求,並使用一些工作程序使用imagemin()
處理請求。
var multer = require('multer')
var upload = multer({ dest: 'your/uploads/' })
// TaskScheduler, a wrapper of a task array
class TaskScheduler extends Array {
constructor (MAX_SLOTS, worker) {
super()
this._MAX_SLOTS= MAX_SLOTS
this._busy_slots= 0
this._worker= worker
}
/**
* Create new tasks
*/
push (...tasks) {
const ret = super.push(...tasks)
this.run()
return ret
}
/**
* Run tasks in available slots
*/
run () {
// if there are any tasks and available slots
while (this.length > 0 && this._busy_slots < this._MAX_SLOTS) {
const firstTask = this.shift()
this._worker(firstTask).then(() => {
// release the slot
this._busy_slots--
// since a task slot is released
// call run() again to process another task from the queue
this.run()
})
this._busy_slots++
}
}
}
// worker is supposed to return a Promise
const scheduler = new TaskScheduler(5, function (task) {
return imagemin.buffer(task.buffer, { /* imagemin options */ })
.then(() => { /* write image files */ })
.catch(() => { /* error handling */ })
})
// schedule the task when there is an incoming request
// the actual code depends on your web server
// here what to do in the callback is the point ;)
// Take express for example, `app` is the express.Application
app.post('your/end/point', upload.fields([{ name: 'myimage' }]), function (req) {
if (req.files.myimage[0]) {
scheduler.push(req.files.myimage[0])
}
})
請注意,由於調度程序是從Array
擴展的,因此可以使用任何Array
方法管理任務,例如pop()
丟棄最后一個任務, shift()
丟棄第一個任務, unshift(newTask)
插入新任務調度程序隊列的開始。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.