节点.js和 CPU 密集型请求

我已经开始修补Node.js HTTP服务器,并且非常喜欢编写服务器端Javascript,但有些事情使我无法开始在我的Web应用程序中使用Node.js。

我理解整个异步 I/O 概念,但我有点担心过程代码占用大量 CPU 的边缘情况,例如图像处理或对大型数据集进行排序。

据我所知,对于简单的网页请求,服务器将非常快,例如查看用户列表或查看博客文章。但是,如果我想编写非常CPU密集型的代码(例如在管理后端)来生成图形或调整数千张图像的大小,则请求将非常慢(几秒钟)。由于此代码不是异步的,因此在这几秒钟内到达服务器的每个请求都将被阻止,直到我的慢速请求完成。

一个建议是将 Web Worker 用于 CPU 密集型任务。但是,我担心Web工作者会很难编写干净的代码,因为它可以通过包含单独的JS文件来工作。如果 CPU 密集型代码位于对象的方法中,该怎么办?为每个CPU密集型方法编写一个JS文件有点糟糕。

另一个建议是生成一个子进程,但这会使代码的可维护性更差。

有什么建议来克服这个(感知的)障碍吗?如何使用 Node 编写干净的面向对象代码.js同时确保异步执行 CPU 密集型任务?


答案 1

这是对Web服务器定义的误解 - 它应该只用于与客户端“交谈”。重负载任务应该委托给独立程序(当然也可以用JS编写)。
你可能会说它是肮脏的,但我向你保证,卡在调整图像大小的Web服务器进程只是更糟(即使对于Apache来说,当它不阻止其他查询时)。不过,您可以使用通用库来避免代码冗余。

编辑:我想出了一个类比;Web应用程序应作为餐厅。你有服务员(网络服务器)和厨师(工人)。服务员与客户联系,做一些简单的任务,如提供菜单或解释某些菜肴是否是素食主义者。另一方面,他们将更艰巨的任务委托给厨房。因为服务员只做简单的事情,他们反应迅速,厨师可以专注于他们的工作。

Node.js这里将是一个单一但非常有才华的服务员,可以一次处理许多请求,而Apache将是一群愚蠢的服务员,每个服务员只处理一个请求。如果这个Node.js服务员开始做饭,那将是一场立竿见影的灾难。尽管如此,烹饪甚至可能会耗尽大量的Apache服务员,更不用说厨房的混乱和责任感的逐渐下降。


答案 2

你需要的是一个任务队列!将长时间运行的任务移出Web服务器是一件好事。将每个任务保存在“单独的”js文件中可以促进模块化和代码重用。它迫使您考虑如何以一种从长远来看更容易调试和维护的方式构建程序。任务队列的另一个好处是工作线程可以用不同的语言编写。只需弹出一个任务,完成工作,然后写回响应。

像这样的东西 https://github.com/resque/resque

这是github的一篇文章,关于他们为什么 http://github.com/blog/542-introducing-resque