java - 在 HTTP 模式下,node.js 是否比 Java 具有实质性的性能优势?

标签 java performance node.js sockets http

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

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

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

我还引用了一篇文章Understanding the node.js event loop ,这也解释了这种情况:

It really is a single thread running: you can’t do any parallel code execution; doing a “sleep” for example will block the server for one second:

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

…however, everything runs in parallel except your code.

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

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

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

更新

I ask this question because some performance evaluation cases are reported, for instance Node.js is taking over the Enterprise – whether you like it or not, and LinkedIn Moved from Rails to Node: 27 Servers Cut and Up to 20x Faster. Some radical opinion claims that J2EE will be totally replaced: J2EE is Dead: Long-live Javascript Backed by JSON Services.

最佳答案

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

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

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

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

关于java - 在 HTTP 模式下,node.js 是否比 Java 具有实质性的性能优势?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16253557/

相关文章:

java - 如何解析放置在 Spring Boot 资源文件夹中的 JSON

java - C# Sort 与 Java Collections.Sort 给出不同的结果

java - ClassPath.getTopLevelClasses() 应该返回 `java.*` 包吗?

c++ - 如何减少这个问题的执行时间(即更快的代码)

node.js - 如何在亚马逊 s3 上删除文件图像

java - 在后增量中更新 for 循环中的变量

java - java Stream.peek() 如何影响字节码?

android - 如何在 Android 系统跟踪中添加自定义标记?

node.js - 在 Postgres 中使用审计表为 NOTIFY/LISTEN 创建触发器是个好主意吗?

node.js - 当我提取图像数据时,它没有从 duckduckgo api 显示