【发布时间】:2021-04-04 21:53:55
【问题描述】:
在我的 express 应用程序中,我在我的应用程序中定义了 2 个端点。一种用于 is-sever-up 检查,一种用于模拟阻塞操作。
app.use('/status', (req, res) => {
res.sendStatus(200);
});
app.use('/p', (req, res) => {
const { logger } = req;
logger.info({ message: 'Start' });
let i = 0;
const max = 10 ** 10;
while (i < max) {
i += 1;
}
res.send(`${i}`);
logger.info({ message: 'End' });
});
我使用 winston 进行日志记录,使用 PM2 进行集群,使用以下命令
$ pm2 start bin/httpServer.js -i 0
它已经启动了 4 个实例。
现在,当我在不同的选项卡中访问/p、/p、/status 按顺序路线时,(请求 1 和请求 2)和(请求 2 和请求 3),我预计会在一段时间后收到请求 1 和请求 2 的响应,但延迟大约 1 秒,请求 3 的响应应该会立即响应。
实际:请求 3 的响应确实立即出现,但请求 1 和请求 2 发生了一些奇怪的事情。请求 2 甚至在请求 1 完成之前才开始。这是我得到的日志。您可以看到请求 1 结束和请求 2 开始的时间戳。
{"message":"Start","requestId":"5c1f85bd-94d9-4333-8a87-30f3b3885d9c","level":"info","timestamp":"2020-12-28 07:34:48"}
{"message":"End","requestId":"5c1f85bd-94d9-4333-8a87-30f3b3885d9c","level":"info","timestamp":"2020-12-28 07:35:03"}
{"message":"Start","requestId":"f1f86f68-1ddf-47b1-ae62-f75c7aa7a58d","level":"info","timestamp":"2020-12-28 07:35:03"}
{"message":"End","requestId":"f1f86f68-1ddf-47b1-ae62-f75c7aa7a58d","level":"info","timestamp":"2020-12-28 07:35:17"}
为什么请求 1 和请求 2 没有同时启动(当然有 1 秒的延迟)?如果它们是同步运行的,为什么请求 3 会立即响应,而不是等待请求 1 和请求 2 完成?
【问题讨论】:
-
是的。 Node.js 是单线程的。因此,执行长时间运行的代码(如 long while 或 for 循环)将导致整个服务器无响应。然而,像 Netflix 和 Twitter 这样的人使用 Node.js 的原因是,Web 服务器很少会运行长时间运行的阻塞任务。相反,99% 的 Web 服务器所做的工作是等待来自其他服务或数据库的响应。等待可以在单线程软件中使用各种异步 I/O API 并行完成。执行代码不能并行完成。
-
但是在这里,我有 4 个实例。所以,我想知道为什么请求 2 没有被另一个实例启动或接收?由于 PM2,所有这些实例都并行运行,对吗?
标签: javascript node.js express pm2 winston