Java 理解 NodeJS 和非阻塞 IO
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18040366/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Understanding NodeJS & Non-Blocking IO
提问by Vishwas Shashidhar
So, I've recently been injected with the Node virus which is spreading in the Programming world very fast.
所以,我最近被注入了 Node 病毒,它在编程世界中传播得非常快。
I am fascinated by it's "Non-Blocking IO" approach and have indeed tried out a couple of programs myself.
我对它的“非阻塞 IO”方法很着迷,并且自己确实尝试了几个程序。
However, I fail to understand certain concepts at the moment.
但是,我目前无法理解某些概念。
I need answers in layman terms (someone coming from a Java background)
我需要外行的答案(来自 Java 背景的人)
1. Multithreading & Non-Blocking IO.
1. 多线程和非阻塞 IO。
Let's consider a practical scenario. Say, we have a website where users can register. Below would be the code.
让我们考虑一个实际场景。比如说,我们有一个用户可以注册的网站。下面是代码。
..
..
// Read HTTP Parameters
// Do some Database work
// Do some file work
// Return a confirmation message
..
..
In a traditional programming language, the above happens in a sequential way. And, if there are multiple requests for registration, the web server creates a new thread and the rest is history. Of course, programmers can create threads of their own to work on Line 2 and Line 3 simultaneously.
在传统的编程语言中,上述过程以顺序方式发生。并且,如果有多个注册请求,Web 服务器会创建一个新线程,其余的都是历史记录。当然,程序员可以创建自己的线程来同时处理第 2 行和第 3 行。
In Node, as I understand, Lines 2 & 3 will be run in parallel while the rest of the program gets executed and the Interpreter polls the lines 2 & 3 every 'x' ms.
在 Node 中,据我所知,第 2 行和第 3 行将并行运行,而程序的其余部分将被执行,并且解释器每“x”毫秒轮询一次第 2 行和第 3 行。
Now, my question is, if Node is a single threaded language, what does the job of lines 2 & 3 while the rest of the program is being executed?
现在,我的问题是,如果 Node 是一种单线程语言,那么在执行程序的其余部分时,第 2 行和第 3 行的工作是什么?
2. Scalability
2. 可扩展性
I recently read that LinkedIn have adapted Node as a back-end for their Mobile Apps and have seen massive improvements.
我最近读到 LinkedIn 已经将 Node 作为其移动应用程序的后端,并且已经看到了巨大的改进。
Can anyone explain how it has made such a difference?
谁能解释一下它是如何产生如此大的不同的?
3. Adapting in other programming languages
3. 适配其他编程语言
If people are claiming that Node to be making a lot of difference when it comes to performance, why haven't other programming languages adapted this Non-Blocking IO paradigm?
如果人们声称 Node 在性能方面有很大的不同,为什么其他编程语言没有采用这种非阻塞 IO 范式?
I'm sure I'm missing something. Only if you can explain me and guide me with some links, would be helpful.
我确定我错过了一些东西。只有你能解释我并用一些链接指导我,才会有帮助。
Thanks.
谢谢。
采纳答案by Nathaniel Travis
A similar question was asked and probably contains all the info you're looking for: How the single threaded non blocking IO model works in Node.js
有人问了一个类似的问题,可能包含您正在寻找的所有信息:How the single threaded nonblocking IO model works in Node.js
But I'll briefly cover your 3 parts:
但我将简要介绍您的 3 个部分:
1.
Lines 2 and 3 in a very simple form could look like:
db.query(..., function(query_data) { ... });
fs.readFile('/path/to/file', function(file_data) { ... });
Now the function(query_data) and function(file_data) are callbacks. The functions db.query and fs.readFile will send the actual I/O requests but the callbacks allow the processing of the data from the database or the file to be delayed until the responses are received. It doesn't really "poll lines 2 and 3". The callbacks are added to an event loop and associated with some file descriptors for their respective I/O events. It then polls the file descriptors to see if they are ready to perform I/O. If they are, it executes the callback functions with the I/O data.
1.
第 2 行和第 3 行的非常简单的形式可能如下所示:
db.query(..., function(query_data) { ... });
fs.readFile('/path/to/file', function(file_data) { ... });
现在 function(query_data) 和 function(file_data) 是callbacks。函数 db.query 和 fs.readFile 将发送实际的 I/O 请求,但回调允许延迟处理来自数据库或文件的数据,直到收到响应。它并不是真正的“轮询第 2 行和第 3 行”。回调被添加到事件循环中,并与它们各自 I/O 事件的一些文件描述符相关联。然后它轮询文件描述符以查看它们是否准备好执行 I/O。如果是,它将使用 I/O 数据执行回调函数。
I think the phrase "Everything runs in parallel except your code" sums it up well. For example, something like "Read HTTP parameters" would execute sequentially, but I/O functions like in lines 2 and 3 are associated with callbacks that are added to the event loop and execute later. So basically the whole point is it doesn't have to wait for I/O.
我认为“除了你的代码之外,一切都并行运行”这句话总结得很好。例如,“读取 HTTP 参数”之类的内容将按顺序执行,但第 2 行和第 3 行中的 I/O 函数与添加到事件循环并稍后执行的回调相关联。所以基本上重点是它不必等待 I/O。
2.
Because of the things explained in 1., Node scales well for I/O intensiverequests and allows many users to be connected simultaneously. It is single threaded, so it doesn't necessarily scale well for CPU intensive tasks.
2.
由于 1. 中解释的事情,Node 可以很好地扩展I/O 密集型请求,并允许多个用户同时连接。它是单线程的,因此对于 CPU 密集型任务不一定能很好地扩展。
3.
This paradigm has been used with JavaScript because JavaScript has support for callbacks, event loops and closures that make this easy. This isn't necessarily true in other languages.
3.
这个范式已经用于 JavaScript,因为 JavaScript 支持回调、事件循环和闭包,使这变得容易。这在其他语言中不一定正确。
I might be a little off, but this is the gist of what's happening.
我可能有点不对劲,但这是正在发生的事情的要点。
回答by cnd
Q1. " what does the job of lines 2 & 3 while the rest of the program is being executed?" Answer: "Nothing". Lines 2 and 3 each themselves starttheir respective jobs, but those jobs cannot be done immediately because (for example) the disk sectors required are not loaded in yet - so the operating system issues a call to the disk to go get those sectors, then "Nothing happens" (node goes on with it's next task) until the disk subsystem (later) issues an interrupt to report they're ready, at which point node returns control to lines #2 and #3.
一季度。“在执行程序的其余部分时,第 2 行和第 3 行的工作是什么?” 回答:“没什么”。第 2 行和第 3 行各自开始各自的作业,但这些作业无法立即完成,因为(例如)所需的磁盘扇区尚未加载 - 因此操作系统向磁盘发出调用以获取这些扇区,然后“什么也没发生”(节点继续执行下一个任务),直到磁盘子系统(稍后)发出中断以报告它们已准备就绪,此时节点将控制权返回给第 2 行和第 3 行。
Q2. single-thread non-blocking dedicates almost no resources to each incoming connection (just some housekeeping data about the connected socket). It's very memory efficient. Traditional web servers "fork" a whole new process to handle each new connection - that means making a humongous copy of every bit of code and data variables needed, and time-slicing the CPU to deal with it all. That's massively wasteful of resources. Thus - if your load is a lot of idle connections waiting for stuff, as was theirs, node makes loads more sense.
Q2。单线程非阻塞几乎没有为每个传入连接分配资源(只是一些关于连接套接字的内务处理数据)。它非常节省内存。传统的 Web 服务器“分叉”一个全新的进程来处理每个新连接——这意味着制作所需的每一位代码和数据变量的庞大副本,并对 CPU 进行时间切片以处理所有这些。这极大地浪费了资源。因此 - 如果您的负载是大量空闲连接等待的东西,就像他们的一样,节点使负载更有意义。
Q3. almost every programming language does already have non-blocking I/O if you want to use it. Node is not a programming language, it's a web server that runs javascript and uses non-blocking I/O (eg: I personally wrote my own identical thing 10 years ago in perl, as did google (in C) when they started, and I'm sure loads of other people have similar web servers too). The non-blocking I/O is not the hard part - getting the programmer to understand how to use it is the tricky bit. Javascript happens to work well for that, because those programmers are already familiar with event programming.
Q3。如果您想使用它,几乎每种编程语言都已经具有非阻塞 I/O。Node 不是一种编程语言,它是一个运行 javascript 并使用非阻塞 I/O 的 Web 服务器(例如:我个人在 10 年前用 perl 编写了我自己的相同的东西,就像谷歌(在 C 中)开始时一样,并且我相信很多其他人也有类似的网络服务器)。非阻塞 I/O 不是难点——让程序员理解如何使用它是一个棘手的部分。Javascript 恰好在这方面工作得很好,因为那些程序员已经熟悉事件编程。
回答by Monz
Even though node.js has been around for a few years, it's performance model is still a bit mysterious.
尽管 node.js 已经存在几年了,它的性能模型仍然有点神秘。
I recently started a blog and decided that the node.js model would be a good first topic since I wanted to understand it better myself and it would be helpful to others to share what I learned. Here are a couple of articles I wrote that explain the high level concepts and some tradeoffs:
我最近开始写一个博客,并决定将 node.js 模型作为一个很好的第一个主题,因为我想自己更好地理解它,并且分享我所学到的知识会对其他人有所帮助。以下是我写的几篇文章,解释了高级概念和一些权衡:
Blocking vs. Non-Blocking I/O – What's going on?