首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在imagemin中限制子进程的数量?

如何在imagemin中限制子进程的数量?
EN

Stack Overflow用户
提问于 2018-04-20 04:33:08
回答 1查看 514关注 0票数 0

我使用,它使用mozjpeg二进制来压缩图像。

问题是,我正在nodejs The服务器中使用它。

这就是它现在的工作方式:

  1. 我正在上传一个JPEG图像使用“请求”模块(fs.createReadStream)。
  2. Multer处理流并将其保存在缓冲区(内存存储)中。
  3. 然后将缓冲区传递给图像素以进行压缩。
  4. 然后将压缩缓冲区写入文件。(example.jpg)

一切都正常。

这里的问题是,对于每个请求,都会产生一个新的mozjpeg二进制进程,即cjpeg。

一个子进程正在消耗12.5MB内存(对于一个.5 MB文件)。

如果同时有50个请求,这将达到大约700 MB,因为对于50个图像,有50个子进程。

有办法限制子进程的数量吗?(库使用"execa“模块)或只生成4-5子进程,它们对所有请求进行压缩。

谢谢

代码语言:javascript
复制
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");
                });

        }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-04-20 07:09:48

解决这个问题的主要概念是限制对imagemin() (产生图像处理过程的人)的调用次数。

也许您可以使用任务队列来收集请求,也可以使用一些工作人员使用imagemin()来处理请求,从而实现任务调度系统。

代码语言:javascript
复制
    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)在调度器队列开始时插入一个新任务。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49934035

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档