Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/444.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Node.js和CPU密集型请求_Javascript_Node.js_Serverside Javascript_Web Worker - Fatal编程技术网

Javascript Node.js和CPU密集型请求

Javascript Node.js和CPU密集型请求,javascript,node.js,serverside-javascript,web-worker,Javascript,Node.js,Serverside Javascript,Web Worker,我已经开始修补Node.js HTTP服务器,并且非常喜欢编写服务器端Javascript,但是有些东西阻止我开始在web应用程序中使用Node.js 我理解整个异步I/O概念,但我有点担心一些边缘情况,其中程序代码非常占用CPU,例如图像处理或对大型数据集进行排序 据我所知,对于简单的网页请求,例如查看用户列表或查看博客文章,服务器将非常快速。但是,如果我想编写非常CPU密集的代码(例如在管理后端)来生成图形或调整数千个图像的大小,那么请求将非常慢(几秒钟)。由于此代码不是异步的,因此在这几秒

我已经开始修补Node.js HTTP服务器,并且非常喜欢编写服务器端Javascript,但是有些东西阻止我开始在web应用程序中使用Node.js

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

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

一个建议是使用Web Workers执行CPU密集型任务。然而,我担心web工作人员将很难编写干净的代码,因为它通过包含一个单独的JS文件来工作。如果CPU密集型代码位于对象的方法中怎么办?为每个CPU密集型方法编写JS文件有点糟糕

另一个建议是生成一个子进程,但这会降低代码的可维护性


有什么建议可以克服这个障碍吗?如何使用Node.js编写干净的面向对象代码,同时确保异步执行CPU繁重的任务

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

编辑:我提出了一个类比;web应用程序应作为餐厅使用。你有服务员(网络服务器)和厨师(工人)。服务员与顾客保持联系,并做一些简单的工作,如提供菜单或解释某道菜是否素食。另一方面,他们把更难的任务委托给厨房。因为服务员只做简单的事情,他们反应很快,厨师可以专心工作


这里的Node.js将是一个单一但非常有才华的服务员,可以一次处理多个请求,而Apache将是一群愚蠢的服务员,每个服务员只处理一个请求。如果这个Node.js服务生开始做饭,那将是一场直接的灾难。尽管如此,烹饪也可能耗尽大量阿帕奇服务员,更不用说厨房的混乱和责任感的逐渐降低了。

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

像这样的


这里有一篇来自github的文章,介绍了他们为什么要构建它,您可以使用两种方法

正如@Tim所指出的,您可以创建一个异步任务,它位于主服务逻辑之外或与主服务逻辑并行。这取决于您的具体需求,但甚至可以作为一种排队机制

WebWorkers可以用于异步进程,但node.js当前不支持它们。有几个扩展提供了支持,例如:


您仍然可以通过标准的“requires”机制重用模块和代码。您只需要确保对工作人员的初始分派传递了处理结果所需的所有信息

您不希望CPU密集型代码执行异步,而是希望它并行执行。您需要从服务HTTP请求的线程中获得处理工作。这是解决这个问题的唯一办法。对于NodeJS,答案是,对于繁重的工作,需要生成子进程。(AFAIK节点没有任何线程/共享内存的概念;它是进程或什么都没有)。对于如何构造应用程序,有两个选项。您可以通过生成8个HTTP服务器并在子进程上同步处理计算密集型任务来获得80/20解决方案。这样做相当简单。你可以花一个小时在那个链接上阅读。事实上,如果你只是在链接顶部剽窃示例代码,你将获得95%的成功率

另一种构造方法是设置作业队列并通过队列发送大型计算任务。请注意,作业队列的IPC有很多开销,因此只有当任务明显大于开销时,这才有用

我感到惊讶的是,这些其他答案甚至都没有提到集群

背景: 异步代码是挂起的代码,直到在其他地方发生某些事情,此时代码将唤醒并继续执行。一种非常常见的情况是,必须在其他地方发生缓慢的事情,即I/O

如果是您的处理器负责执行工作,那么异步代码就没有用处。这正是“计算密集型”任务的情况

现在,异步代码似乎很适合,但事实上它非常常见。它只是碰巧对计算密集型任务没有用处

例如,等待I/O是web服务器中经常出现的一种模式。每个连接到服务器的客户端都有一个套接字。大多数情况下,套接字都是空的。在套接字接收到一些数据之前,您不想做任何事情,此时您需要处理请求。在引擎盖下面是一个HTTP服务器