我有一个在 Nest.Js/Node.Js 上运行的应用程序,它进行文本处理,因此它有一个 .map
(或 .forEach
)迭代需要大量资源(标记一个句子,然后删除停用词等——每个句子可能有数万个)。
为了可重现性,我在下面提供了我使用的代码,没有文本处理细节——只是一个很长的重循环来模拟我的问题:
const before = Date.now()
const statements = [...Array(100)]
let l = 0
let p = 0
const processed =
statements.map((value, index) => {
// a set of consecutive functions that take a long time to execute
for (let i = 0; i < 100000; i++) {
l = l + i * Math.random()
}
// console.log(index + ' ' + l + ' ' + (Date.now() - before))
p = index
return l
})
console.log(processed)
const after = Date.now()
console.log(p + ' results in ' + (after - before) + ' ms')
对于非常大的文件,该进程会占用 100% 的 CPU,因此应用会变得无响应。
我想知道您是否知道任何解决方案可以防止应用占用所有可用的 CPU。比如有没有一种方法可以将任何单个进程设置为占用 80% 而始终为其他用户留出 20%?
PS 我从亚马逊的 ECS 运行它,所以我当然可以创建集群,也可以使用 PM2 进行集群化,但我想知道如何避免 Javascript/Node.Js 应用程序本身的单个进程的 100% 负载。我提到 Nest.Js 框架是因为也许那里也有解决方案。
最佳答案
在限制单个线程使用 100% CPU 方面,有在服务器级别这样做的架构方法,但我认为这并不是您真正想要的结果。使用 100% 的 CPU 不是问题(CPU 通常会在很短的时间内达到 100% CPU 以尽快处理事情),更多的是长时间使用 100% CPU 并防止其他应用程序获取 CPU 周期。
从我在示例代码中看到的情况来看,在 NestJS 中使用队列可能是更好的解决方案。 Documentation can be seen here using Bull.通过这种方式,您可以利用正在处理的作业的速率限制并在那里进行调整,其他应用程序将不会等待整个过程的完成。
例如,如果您有 100,000 个文件要处理,您可能希望创建一个作业来一次处理其中的 1,000 个,并创建 100 个作业以放入队列中。对于需要大量计算时间的进程来说,这是一个相当典型的进程。
我知道这不是我确信您正在寻找的答案,但希望它会有所帮助并提供一个不特定于您的架构的解决方案。
关于javascript - 如何避免 Nest.Js/Node.Js 进程占用 100% 的 CPU?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71482108/