Node.js应该用于密集处理吗?

时间:2012-11-12 20:59:36

标签: javascript node.js mongodb webserver scalability

假设我正在构建一个3层网站,后端有Mongo DB,浏览器中有一些非常轻量级的javascript(假设只是对表单进行验证,可能是几个奇特的控件,它们触发了一些AJAX请求)。

我需要选择一种技术用于'中间'层(我们可以将其细分为子层,但这个细节不是重点,只是整体技术选择),我想要处理一些原始数据超出数据库,并将其渲染成一些HTML,我将其推送到浏览器。一个相当典型的瘦客户端Web架构。

我的安全选择是在Java中实现这个中间层,使用像Jongo这样的库来与Mongo DB交谈,也许Jackson可以编组/解组JSON,以便在他们发出AJAX请求时与我的花哨控件交谈。还有一些Java模板框架,用于在服务器上呈现我的HTML。

但是,我真的很感兴趣将所有这些抛出窗口并将Node.js用于这个中间层,原因如下:

  • 我喜欢javascript(好的部分),让我们说这个应用程序的业务逻辑比Java更具表现力。

  • 到处都是javascript。在堆栈中的任何地方工作时,无需在语言之间切换,实际上也不需要在OO和功能范例之间切换。层之间没有转换管道,JSON在本地无处不在。

  • 我可以在客户端和服务器上重用验证逻辑。

  • 如果将来我决定在浏览器中进行HTML呈现客户端,我可以重复使用现有模板,例如Backbone,只需极少的重构/重新测试工作。

如果你现在和Node一样,以上所有内容都会显而易见。所以我应该选择Node吧?

但是......这就是我失败的地方:因为我们都知道Node基于单线程异步I / O Web服务器模型。这对于我在数据请求服务方面的可扩展性和性能非常有用,但我的业务逻辑呢?我的模板渲染怎么样?这个东西不会对单线程上的所有请求造成巨大的瓶颈吗?

我想到了两个明显的解决方案,但它们都不对:

  1. 将“阻塞”业务逻辑保留在那里,只使用一组Node实例和一个负载均衡器,以真正的并行方式为请求提供服务。好的,那么为什么Node首先不是多线程的呢?或者这总是想法,保持简单愚蠢并避免基本情况下多线程复杂性的可能性,如果需要多核处理能力,程序员可以在此基础上进行额外的设置工作吗?

  2. 保留单个节点实例,并通过调用在其他多线程应用服务器上运行的业务逻辑的某些java实现来保持其不阻塞。好的,这个选项完全取消了我列出的使用Node的所有专业人员(实际上它增加了使用Java的复杂性),而不是可能获得的对数据库的CRUD请求的性能和可扩展性。

  3. 这让我最终得到了我的问题 - 我是否遗漏了Node难题的一些重要部分,我刚刚弄错了事实,或者Node是否不适合在服务器上处理业务逻辑?换句话说,Node是否有用于坐在数据库上并以比I / O阻塞的其他实现更高性能和可扩展的方式为许多CRUD请求提供服务?您必须在以下某个层甚至客户端执行所有业务逻辑,以维持任何合理的性能和可伸缩性级别?

    考虑到Node上的所有嗡嗡声,我宁愿希望它带来更多的信息。我很乐意相信!

1 个答案:

答案 0 :(得分:7)

在任何给定系统上,您都可以使用 N cpus(1-64,或者 N )。在任何CPU密集型应用程序中,您将会遇到 N cpus的吞吐量。通过添加超过 N 线程/进程/其他内容,没有神奇的方法可以解决这个问题。您的代码必须更高效,或者您需要更多的CPU。更多线程无济于事。

关于多CPU性能的一个鲜为人知的事实是,如果您需要同时运行 N + 1 CPU密集型操作,则每个CPU的吞吐量会下降很多。 CPU耗尽的过程往往会在放弃之前长时间挂在CPU上,导致其他任务非常糟糕。在大多数情况下,它阻止了I / O和随之而来的任务切换,这使得现代操作系统多任务工作和它一样有效。如果我们的日常常见任务中有更多是受CPU限制的,我们会发现我们的机器中需要的CPU比现在多得多。

Node.js在服务器方面提高效率的好处是彻底使用每个线程。理想情况下,您最终会减少任务切换。这不是巨大的胜利,但是 N 线程异步处理 N * C 连接将比具有性能优势N * C 阻塞在相同数量的CPU上运行的线程。但是CPU的底线仍然是相同的:如果你有超过 N 的实际CPU工作量,你会感到有些痛苦。

我最后一次查看Node.js API时,有一种方法可以启动一个服务器,每个CPU只有一个监听器和一个工作线程。如果你能做到这一点,我会倾向于使用Node.js,只要满足一些注意事项:

  • Javascript-everywhere方法为您带来一些简单性。对于复杂的事情,我会担心异步编程风格会使事情变得更难而不是更容易。
  • Node.js中的模板处理和其他CPU密集型任务的速度并不比其他语言/平台选择慢得多。
  • 数据库驱动程序可靠。

我可以看到一个缺点:

  • 如果线程崩溃,则会丢失该线程所服务的所有连接。

最后,请记住,程序员时间通常比服务器或带宽更贵。