【问题标题】:in HTTP mode, does node.js have substantial performance advantage over Java?在 HTTP 模式下,node.js 是否比 Java 具有实质性的性能优势?
【发布时间】:2017-02-27 02:55:49
【问题描述】:

我刚刚开始在 node.js 中编写代码一段时间。现在这是我的一个问题:

在 HTTP 应用程序中,给定请求-响应模型,单个应用程序线程被阻塞,直到所有后端任务完成并将响应返回给客户端,所以性能改进似乎仅限于微调后端的事情,比如并行化 IO 请求。 (嗯,当涉及到许多 重度独立 IO 操作时,这种改进很重要,但通常情况还意味着,通过重新设计数据结构,您可以消除大量 IO 请求,并且可能最终获得比仅发出并行操作更好的性能。)

如果是这样,它怎么能比那些基于 Java(或 PHP、python 等)的框架产生更好的性能呢?

我还参考了一篇文章Understanding the node.js event loop,也说明了这种情况:

真的是单线程运行:你不能做任何并行代码 执行;例如,做一个“睡眠”会阻塞服务器一个 第二:

while(new Date().getTime() < now + 1000) {
   // do nothing
}

...但是,除了您的代码之外,所有内容都是并行运行的。

我个人通过将确切的“睡眠”代码放入一个 IO 回调闭包中验证了这一点,并尝试提交导致此回调的请求,然后提交另一个。这两个请求在处理时都会触发控制台日志。而我的观察是,后者被阻止,直到前者返回响应。

那么,这是否意味着只有在socket模式下,双方都可以随时向对方发出事件和推送消息,才能发挥异步处理能力的全部威力?

我对此有点困惑。欢迎任何意见或建议。谢谢!

更新

我问这个问题是因为一些绩效评估案例是 报告,例如Node.js is taking over the Enterprise – whether you like it or not, 和LinkedIn Moved from Rails to Node: 27 Servers Cut and Up to 20x Faster。 一些激进的观点声称 J2EE 将被完全取代:J2EE is Dead: Long-live Javascript Backed by JSON Services

【问题讨论】:

标签: java performance node.js sockets http


【解决方案1】:

NodeJS 使用 libuv,所以 IO 操作是非阻塞的。是的,您的 Node 应用程序使用 1 个线程,但是,所有 IO 请求都被推送到事件队列。那么当请求发出时,很明显它的响应不会在零时刻从socket、文件等中读取。因此,队列中准备好的任何内容都会弹出并进行处理。同时,您的请求可以得到答复,可能有要读取的块或完整数据,但它们只是在队列中等待处理。这一直持续到没有事件剩余,或者打开的套接字被关闭。然后 NodeJS 终于可以结束它的执行了。

如您所见,NodeJS 不像其他框架,完全不同。如果你有一个长期的非 IO 操作,所以它是阻塞的,比如矩阵操作,图像和视频处理,你可以生成另一个进程并分配给他们工作,使用消息传递,你喜欢 TCP,IPC 的方式。

NodeJS 的主要目的是消除不必要的上下文切换,这些切换在不正确使用时会带来巨大的开销。在 NodeJS 中,为什么需要上下文切换?所有作业都被推送到事件队列,并且它们的计算量可能很小,因为它们所做的一切都是为了产生多个 IO/s,(从数据库读取、更新数据库、写入客户端、写入裸 TCP 套接字、从缓存读取),在中间阻止他们并转向另一份工作是不合逻辑的。所以在 libuv 的帮助下,任何一个准备好的 IO 都可以立即执行。

如需参考,请查看 libuv 文档:http://nikhilm.github.io/uvbook/basics.html#event-loops

【讨论】:

  • 谢谢。该应用程序可以初始化多个并行化的 IO 任务,但这不是问题。我担心的是,在 HTTP 模式下,它必须等待所有后端事情完成才能响应,然后才能处理另一个请求。
  • 当“在 HTTP 模式下,它必须等待所有后端事情完成”才能处理另一个请求时,这是不正确的——这就是重点。节点可以在等待从第一个请求完成的 IO 操作时开始/继续处理其他请求。
  • 从本质上讲,Node 可以不浪费任何 CPU 时间,这在 IO 操作同步时是不可能的。正如@RoelvanUden 所提到的,通过每个核心拥有一个 Node 进程,您可以充分提高性能。
【解决方案2】:

与 Java 相比,我还注意到很多关于 Node.js 性能的激进观点。从排队理论的角度来看,我怀疑一个没有阻塞的单个线程如何能够执行多个阻塞的线程。我想我会用自己的investigation 来了解 Node.js 与更成熟和成熟的技术相比表现如何。

我通过在 Node.js 和 DropWizard / Java 中编写功能相同的多数据源微服务来评估 Node.js,然后对两个实现进行相同的负载测试。我收集了两个测试结果的性能测量结果并分析了数据。

Node.js 的代码大小只有五分之一,延迟与 DropWizard 相当,吞吐量低 16%。

我可以看到 Node.js 是如何吸引早期初创公司的。在 Node.js 中快速编写微服务并使其运行比使用 Java 更容易。随着公司的成熟,他们的重点往往会从寻找适合的产品/市场转向提高规模经济。这或许可以解释为什么更成熟的公司更喜欢具有更高可扩展性的 Java。

【讨论】:

    【解决方案3】:

    就我对 node.js 的经验(虽然简短)而言,我同意 node.js 服务器的性能无法与其他 web 服务器(如tomcat 等)进行比较,如 node.js doc 某处所述

    真的是单线程运行:你不能做任何并行代码 执行;例如,做一个“睡眠”会阻塞服务器一个 第二:

    所以我们使用它不是像 tomcat 这样的成熟网络服务器的替代品,而只是为了分散来自 tomcat 的一些负载,我们可以在其中采用单线程模型。所以它必须在某个地方进行权衡

    另见http://www.sitepoint.com/node-js-is-the-new-black/这是一篇关于node.js的精彩文章

    【讨论】:

    • 您可以将您的进程集群化为每个核心使用一个进程,从而有效地使用您所有的可用资源。
    猜你喜欢
    • 2011-12-18
    • 1970-01-01
    • 1970-01-01
    • 2023-03-04
    • 1970-01-01
    • 2019-08-21
    • 1970-01-01
    • 2021-05-30
    • 2016-08-19
    相关资源
    最近更新 更多