【发布时间】:2020-10-14 23:39:10
【问题描述】:
当 nodejs 服务器被阻塞时,传入的请求会发生什么?有时服务器会被阻塞,因为它正在处理一些计算成本很高的东西,或者可能正在执行一些同步 IO(例如写入 sqlite 数据库)。最好用一个例子来描述:
给定这样的服务器:
const { execSync } = require('child_process')
const express = require('express')
const app = express()
const port = 3000
// a synchronous (blocking) sleep function
function sleep(ms) {
execSync(`sleep ${ms / 1000}`)
}
app.get('/block', (req, res) => {
sleep(req.query.ms)
res.send(`Process blocked for ${req.query.ms}ms.`)
})
app.get('/time', (req, res) => res.send(new Date()))
app.listen(port, () => console.log(`Example app listening at http://localhost:${port}`))
我可以像这样阻止nodejs进程:
# block the server for two seconds
curl http://localhost:3000/block\?ms\=2000
当它被阻止时尝试向服务器发出另一个请求:
curl http://localhost:3000/time
第二个请求将挂起,直到阻塞调用完成,然后以预期的日期时间响应。我的问题是,当 nodejs 进程被阻塞时,请求具体发生了什么?
- 节点是否使用一些低级 c++ 读取请求并将其放入队列中?这里涉及背压吗?
- 这里涉及到unix内核吗?它是否知道在服务器拒绝响应时将请求放入某种队列?
- 是否就像 curl 无限期地等待来自套接字的响应一样简单?
- 如果服务器被阻塞并且有 10,000 个新请求访问服务器会发生什么?一旦服务器畅通,它们都会得到服务吗? (假设客户端和服务器之间没有负载均衡器或其他超时机制)
最后,我知道阻止 nodejs 是不好的做法,但我并不是在询问最佳做法。我想了解 nodejs 在此处描述的压力情况下会做什么。
【问题讨论】:
标签: node.js http server backpressure