19

所以,我最近被注入了 Node 病毒,它在编程世界中传播得非常快。

我对它的“非阻塞 IO”方法很着迷,并且自己确实尝试了几个程序。

但是,我目前无法理解某些概念。

我需要外行的答案(来自 Java 背景的人)

1.多线程和非阻塞IO。

让我们考虑一个实际场景。比如说,我们有一个用户可以注册的网站。下面是代码。

..
..
   // Read HTTP Parameters
   // Do some Database work
   // Do some file work
   // Return a confirmation message
..
..

在传统的编程语言中,上述情况以顺序方式发生。而且,如果有多个注册请求,Web 服务器会创建一个新线程,剩下的就是历史记录。当然,程序员可以创建自己的线程来同时处理第 2 行和第 3 行。

据我了解,在 Node 中,第 2 行和第 3 行将并行运行,而程序的其余部分将被执行,并且解释器每“x”毫秒轮询第 2 行和第 3 行。

现在,我的问题是,如果 Node 是一种单线程语言,那么在执行程序的其余部分时,第 2 行和第 3 行的工作是什么?

2. 可扩展性

我最近读到 LinkedIn 已经将 Node 作为其移动应用程序的后端进行了调整,并且已经看到了巨大的改进。

谁能解释它是如何产生如此不同的影响的?

3. 适应其他编程语言

如果人们声称 Node 在性能方面有很大的不同,为什么其他编程语言没有采用这种非阻塞 IO 范式?

我确定我错过了一些东西。只有您可以向我解释并通过一些链接指导我,才会有所帮助。

谢谢。

4

3 回答 3

13

有人问了一个类似的问题,可能包含您正在寻找的所有信息:单线程非阻塞 IO 模型在 Node.js 中的工作原理

但我将简要介绍您的 3 个部分:

1.
第 2 行和第 3 行的形式非常简单:
      db.query(..., function(query_data) { ... });
      fs.readFile('/path/to/file', function(file_data) { ... });

现在 function(query_data) 和 function(file_data) 是回调。函数 db.query 和 fs.readFile 将发送实际的 I/O 请求,但回调允许延迟处理来自数据库或文件的数据,直到收到响应。它并不是真正的“轮询第 2 行和第 3 行”。回调被添加到事件循环中,并与它们各自的 I/O 事件的一些文件描述符相关联。然后它轮询文件描述符以查看它们是否已准备好执行 I/O。如果是,它会使用 I/O 数据执行回调函数。

我认为“除了你的代码之外,一切都并行运行”这句话总结得很好。例如,“读取 HTTP 参数”之类的内容将按顺序执行,但第 2 行和第 3 行中的 I/O 函数与添加到事件循环并稍后执行的回调相关联。所以基本上重点是它不必等待 I/O

2.
由于 1. 中解释的事情,Node 可以很好地适应I/O 密集型请求,并允许同时连接许多用户。它是单线程的,因此它不一定能很好地适应 CPU 密集型任务。

3.
这种范式已与 JavaScript 一起使用,因为 JavaScript 支持回调、事件循环和闭包,使这变得容易。这在其他语言中不一定正确。

我可能有点偏离,但这是正在发生的事情的要点。

于 2013-08-04T07:22:53.707 回答
3

Q1。“在执行程序的其余部分时,第 2 行和第 3 行的工作是什么?” 答案:“没什么”。第 2 行和第 3 行各自开始各自的工作,但这些工作无法立即完成,因为(例如)所需的磁盘扇区尚未加载 - 所以操作系统发出对磁盘的调用以获取这些扇区,然后“什么都没有发生”(节点继续它的下一个任务),直到磁盘子系统(稍后)发出中断以报告它们已准备好,此时节点将控制权返回到第 2 行和第 3 行。

Q2。单线程非阻塞几乎不为每个传入连接分配任何资源(只是一些有关已连接套接字的内务数据)。它非常节省内存。传统的 Web 服务器“分叉”一个全新的进程来处理每个新连接——这意味着对所需的每一位代码和数据变量进行巨大的复制,并对 CPU 进行时间切片来处理这一切。这是对资源的极大浪费。因此 - 如果您的负载是大量空闲连接等待的东西,就像他们的一样,节点使负载更有意义。

Q3。如果您想使用它,几乎每种编程语言都已经具有非阻塞 I/O。Node 不是一种编程语言,它是一个运行 javascript 并使用非阻塞 I/O 的 Web 服务器(例如:我个人在 10 年前用 perl 编写了我自己的相同东西,就像谷歌(在 C 中)刚开始时一样,并且我敢肯定很多其他人也有类似的网络服务器)。非阻塞 I/O 不是难点——让程序员了解如何使用它是一个棘手的问题。Javascript 恰好可以很好地解决这个问题,因为那些程序员已经熟悉事件编程。

于 2014-12-12T12:48:33.790 回答
1

尽管 node.js 已经存在了几年,但它的性能模型仍然有点神秘。

我最近创建了一个博客,并决定将 node.js 模型作为一个很好的第一个主题,因为我想自己更好地理解它,并且分享我学到的东西会对其他人有所帮助。以下是我写的几篇文章,解释了高级概念和一些权衡:

阻塞与非阻塞 I/O – 发生了什么?

了解 node.js 性能

于 2015-10-09T21:46:36.000 回答