我如何 运行 另一个 EC2 实例上的部分代码
How I Can Run Some Part of the Code on another EC2 instance
我在 EC2 实例 上有一个 NodeJS 应用程序 运行ning,它具有一些用户可以录制多个视频的功能。
当用户注销时,我正在使用 ffmpeg(版本 4.2.4)将所有这些视频组合成一个视频。
我录制的是WEBM
格式的视频,最后的单视频应该是MP4
格式的。
假设用户录制了 3 个视频,每个视频 10 分钟,那么最后当用户退出时,所有这 3 个视频应该合并为一个长度为 30 分钟的视频。
现在一切正常,但是当所有对话和连接都在进行时,CPU 使用率很高。
CPU 使用率有时高达 60-70%
我遵循的过程是
将 webm
文件转换为 mp4
文件。
ffmpeg -i input_file.webm -c:v copy -c:a copy output_file.mp4
将 MP4 转换为 ts(传输流)文件。
ffmpeg -i output_file.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts OUTPUT_MP4.ts
我正在按照这个过程将所有 mp4 文件连接成一个文件。
连接文件
ffmpeg -i "concat:OUTPUT_MP4_1.ts|OUTPUT_MP4_2.ts|OUTPUT_MP4_3.ts" -c copy -bsf:a aac_adtstoasc FINAL_MP4_SINGLE_FILE.mp4
所有这个过程都很耗时(但不是优先级),但是,这个过程占用了 CPU 很多。
如果我的应用程序上有很多用户并且可能正在进行视频转换,服务器可能会崩溃或变慢。
现在,我的问题是如何 运行 在 专用 EC2 instance
上进行此转换过程,其中只能进行转换而不能进行任何其他工作,来自与第一个 EC2 实例 运行ning 相同的代码。
您将需要一个后处理任务的工作队列。一个简单的 Javascript 数组可以用作队列:您 .push()
将新项目放入队列,然后 .shift()
将它们取出以使用它们。
您将需要一个循环函数来使用队列,看起来像这样。
async function convertVideo (queue, completed) {
while (true) {
if (queue.length === 0) {
await sleep(1000)
continue
}
const item = queue.shift()
await convertItem(item)
completed.add(item)
}
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
此函数将 运行 您的 convertItem()
一次作用于一项。在程序启动时调用此函数一次。给它排队。
我扔了一个 Set 来存放完成的项目。
const queue = []
const completed = new Set()
convertVideo(queue, completed).next()
您可能希望以不同的方式处理完成。
这不是 运行 不同虚拟机上的转换。但它确实可以防止您的单个实例过载。
您可以通过以下方式增加容量:
- 向您的 VM 添加核心,运行 convertVideo 函数两次以获得两个并发转换操作。
- 添加具有相同服务器软件的新 VM 并平衡传入请求。
如果您必须 运行 在不同的 VM 上进行转换,您需要某种 VM 间排队方案,以便您的 Web 服务器计算机可以将工作项传递给转换机器。 Amazon SQS, redis, and RabbitMQ 是 VM 间排队技术的可能选择。还有其他人。如果不深入了解您的应用程序的工作方式,就很难给出详细的建议。
如果你使用单独的虚拟机进行处理,你会发现AWS弹性转码服务已经解决了所有关于排队的操作细节。它很昂贵,但 24x7 全天候运行多核 EC2 实例也是如此。
我在 EC2 实例 上有一个 NodeJS 应用程序 运行ning,它具有一些用户可以录制多个视频的功能。
当用户注销时,我正在使用 ffmpeg(版本 4.2.4)将所有这些视频组合成一个视频。
我录制的是WEBM
格式的视频,最后的单视频应该是MP4
格式的。
假设用户录制了 3 个视频,每个视频 10 分钟,那么最后当用户退出时,所有这 3 个视频应该合并为一个长度为 30 分钟的视频。
现在一切正常,但是当所有对话和连接都在进行时,CPU 使用率很高。
CPU 使用率有时高达 60-70%
我遵循的过程是
将
webm
文件转换为mp4
文件。ffmpeg -i input_file.webm -c:v copy -c:a copy output_file.mp4
将 MP4 转换为 ts(传输流)文件。
ffmpeg -i output_file.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts OUTPUT_MP4.ts
我正在按照这个过程将所有 mp4 文件连接成一个文件。
连接文件
ffmpeg -i "concat:OUTPUT_MP4_1.ts|OUTPUT_MP4_2.ts|OUTPUT_MP4_3.ts" -c copy -bsf:a aac_adtstoasc FINAL_MP4_SINGLE_FILE.mp4
所有这个过程都很耗时(但不是优先级),但是,这个过程占用了 CPU 很多。
如果我的应用程序上有很多用户并且可能正在进行视频转换,服务器可能会崩溃或变慢。
现在,我的问题是如何 运行 在 专用 EC2 instance
上进行此转换过程,其中只能进行转换而不能进行任何其他工作,来自与第一个 EC2 实例 运行ning 相同的代码。
您将需要一个后处理任务的工作队列。一个简单的 Javascript 数组可以用作队列:您 .push()
将新项目放入队列,然后 .shift()
将它们取出以使用它们。
您将需要一个循环函数来使用队列,看起来像这样。
async function convertVideo (queue, completed) {
while (true) {
if (queue.length === 0) {
await sleep(1000)
continue
}
const item = queue.shift()
await convertItem(item)
completed.add(item)
}
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
此函数将 运行 您的 convertItem()
一次作用于一项。在程序启动时调用此函数一次。给它排队。
我扔了一个 Set 来存放完成的项目。
const queue = []
const completed = new Set()
convertVideo(queue, completed).next()
您可能希望以不同的方式处理完成。
这不是 运行 不同虚拟机上的转换。但它确实可以防止您的单个实例过载。
您可以通过以下方式增加容量:
- 向您的 VM 添加核心,运行 convertVideo 函数两次以获得两个并发转换操作。
- 添加具有相同服务器软件的新 VM 并平衡传入请求。
如果您必须 运行 在不同的 VM 上进行转换,您需要某种 VM 间排队方案,以便您的 Web 服务器计算机可以将工作项传递给转换机器。 Amazon SQS, redis, and RabbitMQ 是 VM 间排队技术的可能选择。还有其他人。如果不深入了解您的应用程序的工作方式,就很难给出详细的建议。
如果你使用单独的虚拟机进行处理,你会发现AWS弹性转码服务已经解决了所有关于排队的操作细节。它很昂贵,但 24x7 全天候运行多核 EC2 实例也是如此。