Node.js 当多个I/O操作发生时,单线程如何处理并发
Node JS是最受欢迎的运行环境之一,用于构建后端服务器。尽管它是单线程的,但由于其异步和非阻塞的行为,Node JS表现得非常出色。它经常用于构建与网站、移动应用程序等进行交互的后端服务器。让我们看看这个话题-
单线程Node JS在多个I/O操作发生时如何处理并发?
这意味着Node JS在使用单个线程时如何处理多个客户端请求?使用单个线程意味着一次只能处理一个客户端的请求和响应。那么当多个客户端发出请求时,Node JS是如何工作的呢?
Node JS使用异步和非阻塞行为的概念。但首先,让我们了解以下术语: 单线程 和 并发 。
- 单线程: Node JS使用单个线程工作。这意味着没有一个线程池被分配来处理客户端请求,而只有一个线程用于接受传入的请求。因此,即使有100个客户端,我们也只有一个线程在一个服务器上处理它们。
- 并发: 当多个客户端同时发出请求时,这被称为并发。例如,Google的官方网站每天都有数百人同时访问。这就是并发。
让我们看一下处理客户端请求的方法:
1. 同步和阻塞行为: 这意味着线程将接受一个客户端请求,将其发送到另一个服务器或数据库,并等待响应(阻塞行为)。一旦收到响应,它将将响应返回给客户端,然后接受第二个客户端的请求(同步)。这意味着后续的客户端必须等待他们的响应,直到前面的客户端收到他们的响应,这在我们的案例中是不可行的。
2. 异步和非阻塞行为: 这是Node JS使用的方法。这意味着线程将接受第一个客户端的请求,将请求发送到一个工作线程池,并变得空闲以接受第二个客户端的请求(非阻塞行为)。这样它就可以同时处理多个或并发的客户端请求。一旦响应准备好,线程池通过回调将其发送回主线程(异步行为)。一旦线程接收到响应,它将响应返回给相应的客户端。这就是Node JS处理并发的方式。
让我们通过以下代码示例来理解:
注意: 创建一个名为server.js的文件,我们将在两个示例中使用它:
示例1: 在这个示例中,我们将看到如何处理单个客户端请求:
const express = require('express');
const app = express();
const port = 5000;
app.get('/', (req, res) => {
res.send('Hello World!');
console.log('Hello World!');
})
app.listen(port, () => {
console.log(`Server is running at the port: ${port}`);
})
运行服务器的步骤:
使用以下命令运行代码:
node server.js
输出: 现在请打开您的浏览器,在地址栏中输入 http://localhost:5000/。您将会看到一个页面上显示”Hello World”的字样。
Server is running at the port: 5000
Hello World!
解释: 所以,代码的作用是,在URL http://localhost:5000/ 上接收客户端请求,使用 app.get 发送输出到客户端使用 res.send . 同时,我们在控制台中打印输出,使用console.log.
示例2: 在这个示例中,我们将看到如何处理多个或并发的客户端请求:
const express = require('express');
const app = express();
const port = 5000;
const multipleClients = async () => {
await console.log('Hello World!');
}
app.get('/', (req, res) => {
multipleClients();
})
app.listen(port, () => {
console.log(`Server is running at the port: ${port}`);
})
运行服务器的步骤:使用以下命令运行代码:
node server.js
输出:
现在,打开你的浏览器,在多个标签页中输入http://localhost:5000/。在这种情况下,我使用了三个标签页。现在返回到你的控制台。你应该得到以下输出:
Server is running at the port: 5000
Hello World!
Hello World!
Hello World!
解释: 如您所见,有一部分与上一个示例相似。在这种情况下,我们正在创建一个名为 multipleClients 的新函数。这是一个异步函数。我们使用了 async 关键字。因此,当我们向URL http://localhost:5000/发出多个客户端请求时, app.get 调用了函数multipleClients。由于这是一个异步函数,主线程将该请求发送到工作线程池并等待响应。值得注意的是,我们使用 await 来达到相同的目的。然后该线程变为空闲状态,可以接受来自另一个用户的请求。当线程池向主线程返回响应时,主线程将响应返回给客户端,并且我们可以在控制台中看到输出为’ Hello World! ‘。这展示了Node JS的异步和非阻塞行为。
这就是我们如何在Node JS中处理并发性,使用 async 和 await 关键字。