如何在 NodeJS 中处理 CPU 密集型任务的多个请求?
How to handle multiple requests for CPU intensive tasks in NodeJS?
在我的 NodeJS 中,有一个巨大的处理任务,包括从 IBM 云下载大约 600MB 的音频文件(8-10 个音频,每个大约 70MB),然后使用 FFMPEG https://www.npmjs.com/package/ffmpeg.音频处理需要大约 5 分钟的大量时间。这个过程是异步的,所以我的前端会响应。
如何处理对同一音频处理的多个请求,但问题是多个请求将有不同的音频要下载和处理,因此在处理多个请求时可能会出现竞争条件。通过阅读其他堆栈溢出答案,我了解到有创建子进程或工作线程等方法。适合我的用例的方法是什么?我如何确保不满足竞争条件?
背景
我有过类似的经历,不过是视频转换和处理。我不得不使用 ffmpeg
将视频转换为不同的容器和质量格式。
解决方案
对于我的场景,解决此问题的最佳方法是创建一个作业队列。我使用了 celery
并且它能够很好地处理它。
您的用例的等效项是 - https://github.com/mher/node-celery
您将不得不产生一些工作人员,这些工作人员将从 RabbitMQ
等消息队列数据库中分配任务。任务完成后,他们异步发回响应。希望这适用于你的场景
从 ffmpeg 模块的文档中我们看到:
This library provides a set of functions and utilities to abstract commands-line usage of ffmpeg.
看了下ffmpeg模块的源码,发现实现的核心是这样的:
utils.exec([ffmpeg.bin,'-formats','2>&1'], settings, ...
其中utils.exec
基本上是这样的:
child_process.exec(finalCommand, settings, ...
所以基本上 ffmpeg 模块已经在使用子进程来执行 CPU 密集型任务。这意味着 node.js 没有执行任何 CPU 密集型任务。
这意味着您不需要做任何额外的事情来处理多个请求。您执行的任何其他操作只会使用更多 RAM,而不会带来任何性能优势。
如何缩放:
缩放这在任何语言中都是相同的,因为您的服务器基本上已经 multi-threaded/multi-processing。只需使用具有更多内核的 CPU。
扩展超越 CPU:
Netflix 和 YouTube 等大型服务可以并行处理数以万计的媒体。显然你买不到几万核的CPU。扩展的方式是在多个 CPUs/servers 之间对服务进行负载平衡,而不是直接使用 ffmpeg:
┌─────────────────┐ ┌─────────────────────┐
│ node web server │ --------> │ node ffmpeg servers │┐
└─────────────────┘ └┬────────────────────┘│┐
└┬────────────────────┘│
└─────────────────────┘
在我的 NodeJS 中,有一个巨大的处理任务,包括从 IBM 云下载大约 600MB 的音频文件(8-10 个音频,每个大约 70MB),然后使用 FFMPEG https://www.npmjs.com/package/ffmpeg.音频处理需要大约 5 分钟的大量时间。这个过程是异步的,所以我的前端会响应。
如何处理对同一音频处理的多个请求,但问题是多个请求将有不同的音频要下载和处理,因此在处理多个请求时可能会出现竞争条件。通过阅读其他堆栈溢出答案,我了解到有创建子进程或工作线程等方法。适合我的用例的方法是什么?我如何确保不满足竞争条件?
背景
我有过类似的经历,不过是视频转换和处理。我不得不使用 ffmpeg
将视频转换为不同的容器和质量格式。
解决方案
对于我的场景,解决此问题的最佳方法是创建一个作业队列。我使用了 celery
并且它能够很好地处理它。
您的用例的等效项是 - https://github.com/mher/node-celery
您将不得不产生一些工作人员,这些工作人员将从 RabbitMQ
等消息队列数据库中分配任务。任务完成后,他们异步发回响应。希望这适用于你的场景
从 ffmpeg 模块的文档中我们看到:
This library provides a set of functions and utilities to abstract commands-line usage of ffmpeg.
看了下ffmpeg模块的源码,发现实现的核心是这样的:
utils.exec([ffmpeg.bin,'-formats','2>&1'], settings, ...
其中utils.exec
基本上是这样的:
child_process.exec(finalCommand, settings, ...
所以基本上 ffmpeg 模块已经在使用子进程来执行 CPU 密集型任务。这意味着 node.js 没有执行任何 CPU 密集型任务。
这意味着您不需要做任何额外的事情来处理多个请求。您执行的任何其他操作只会使用更多 RAM,而不会带来任何性能优势。
如何缩放:
缩放这在任何语言中都是相同的,因为您的服务器基本上已经 multi-threaded/multi-processing。只需使用具有更多内核的 CPU。
扩展超越 CPU:
Netflix 和 YouTube 等大型服务可以并行处理数以万计的媒体。显然你买不到几万核的CPU。扩展的方式是在多个 CPUs/servers 之间对服务进行负载平衡,而不是直接使用 ffmpeg:
┌─────────────────┐ ┌─────────────────────┐
│ node web server │ --------> │ node ffmpeg servers │┐
└─────────────────┘ └┬────────────────────┘│┐
└┬────────────────────┘│
└─────────────────────┘