【问题标题】:Node - getting ENOMEM error when spawning child process节点 - 生成子进程时出现 ENOMEM 错误
【发布时间】:2021-12-30 08:35:26
【问题描述】:

我在具有5120 CPU8192 Memory 的AWS ECS 机器上运行节点14。 有时在重负载下运行(使用imagemin 压缩大量图像或使用S3 同步将文件从S3 复制到本地计算机)我收到ENOMEM 错误。

这会导致 ECS 实例崩溃。

S3 同步命令通过 child_process spawn 执行,而 imagemin 包还生成一个子进程以压缩图像。 两个错误都显示在下方

(node:23) UnhandledPromiseRejectionWarning: Error: spawn ENOMEM
    at ChildProcess.spawn (internal/child_process.js:403:11)
    at spawn (child_process.js:553:9)
    at new SpawnTimeout (/app/src/utils/SpawnTimeout.ts:33:25)
    at s3Cp (/app/src/utils/s3.utils.ts:62:24)
    at copyFile (/app/src/utils/s3.utils.ts:52:10)
    at executeImageCompression (/app/src/processors/Processor.ts:63:9)

我尝试增加 ECS 资源并添加自定义 -max-old-space-size 但没有帮助。

我看到了这个帖子 - Node.js catch ENOMEM error thrown after spawn

但我无法在 docker 中配置 --memory-swap 参数,因为部署是由其他人控制的。

请告诉我如何解决这个问题?

【问题讨论】:

  • 您好,您能告诉我们您在尝试增加 ECS 资源时使用的命令/选项及其值吗?
  • 我创建了一个新的任务定义并更新了那里的值。
  • 这是因为系统操作系统内存不足,Node.js(V8) 无法生成新进程。请注意,每个子进程都是一个独立的进程,并且会消耗大量内存。
  • @iKoala 我尝试将并发子进程的数量限制为 25 而不是 100,但仍然出现相同的错误。

标签: node.js amazon-ecs imagemin


【解决方案1】:

内存分配给您调用的每个 child_process.spawn()。据我所知,imagemin 调用 child_process.spawn() 的次数可能超过了计算机可以处理的次数,导致 nodejs 分配的内存比计算机分配给新生成的 child_processes 的内存多,从而导致 ENOMEM 错误。要么,要么进程可能占用太多内存。这只是我的猜测,因为我看不到代码。

您可以尝试减少或限制正在生成的新子进程的数量。

同样,此解决方案纯粹是推测性的,因为我无法访问您的代码,因此如果您可以将其添加到您的问题中将会很有帮助。

此链接可能会进一步帮助您: How can I limit the number of child proccesses in imagemin?

【讨论】:

  • 我尝试将并发子进程的数量限制为 25 个而不是 100 个,但仍然出现相同的错误。
  • 最佳实践是将子进程的数量限制为您机器的 CPU 内核数量。除此之外添加更多的子进程不会增加太多的性能差异。如果您已经这样做了,您可以检查每个子进程在此library 的峰值使用了多少内存,然后将总内存除以每个子进程所需的内存。分配一些“缓冲”内存以确保子进程不会占用所有内存。希望这会有所帮助!