当进程被阻止时,nodejs服务器请求会发生什么

时间:2020-06-24 16:23:15

标签: node.js http server backpressure

当Node.js服务器被阻止时,传入请求会如何处理?有时,由于服务器正在消耗大量计算资源或执行某些同步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在压力很大的情况下会做什么。

1 个答案:

答案 0 :(得分:0)

在OS中,如果主机应用程序太忙而无法立即进行拾取,则TCP堆栈具有一个队列,用于等待传入数据或连接,该队列正等待相应的主机应用程序进行拾取。根据操作系统和配置的不同,入站队列有时会填满,尝试连接的客户端会收到错误消息。我不知道nodejs中有任何单独的线程将它们归入自己的队列,并且由于TCP堆栈已经自行实现了入站连接队列,因此没有理由让nodejs这么做。

如果您要阻塞nodejs进程足够长时间以至于10,000个传入请求到达,那么您将面临更大的问题,并且需要从根本上解决阻塞问题。 Nodejs具有线程,子进程和群集,所有这些都可以用作缓解阻塞计算的方法。

对于在现有的,已经打开的TCP连接上发送的数据,存在背压(在TCP级别)。对于新的传入连接,实际上不存在背压之类的问题。新的传入连接被接受或不被接受。这是我们有时观察到的ERR_CONNECTION_REFUSED的原因之一。

此处有一些相关的讨论:What can be the reason of connection refused errors

节点是否使用一些底层c ++读取请求并将其放入队列?这里有背压吗?

Node本身不执行此操作(我知道)。 OS TCP堆栈具有用于入站数据和传入连接请求的队列。

这里是否包含unix内核?是否知道在服务器拒绝响应时将请求放入某种队列?

(在OS中)TCP堆栈确实有​​一个队列,用于到达现有连接的传入数据和入站连接请求。此队列的大小是有限的(并且可以部分配置)。

就像curl无限期地等待套接字响应一样简单吗?

不。如果服务器上的入站连接请求队列已满,则连接请求将被拒绝。如果队列未满,则只需等待足够长的时间就可以成功。大多数客户端库都会使用某种超时方式,并在一段时间后放弃,以防万一发生某些事情导致永远不会发送回响应。

如果服务器被阻止并且有10,000个新请求到达服务器,会发生什么?解除阻塞服务器后,是否将全部对它们进行维修? (假设客户端与服务器之间没有负载均衡器或其他超时机制)

目标主机将入站连接请求排队到一个最大限制(具体取决于操作系统和配置),然后将拒绝之后的请求。


其他一些相关文章:

How TCP backlog works in Linux

What is "backlog" in TCP connections?

TCP Connection Backlog and a Struggling Server

您阅读的这类文章越多,您就会发现在快速接受大量连接与防御各种类型的DOS攻击之间进行权衡。看来必须要取得平衡。