Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 当进程被阻止时,nodejs服务器请求会发生什么情况_Node.js_Http_Server_Backpressure - Fatal编程技术网

Node.js 当进程被阻止时,nodejs服务器请求会发生什么情况

Node.js 当进程被阻止时,nodejs服务器请求会发生什么情况,node.js,http,server,backpressure,Node.js,Http,Server,Backpressure,当nodejs服务器被阻止时,传入的请求会发生什么情况?有时,服务器会被阻塞,因为它正在仔细检查一些计算成本很高的东西,或者可能正在执行一些同步IO(例如,写入sqlite数据库)。最好用一个例子来描述这一点: 给定这样的服务器: const{execSync}=require('child_process') const express=require('express') const app=express() 常数端口=3000 //同步(阻塞)睡眠功能 功能睡眠(ms){ execSyn

当nodejs服务器被阻止时,传入的请求会发生什么情况?有时,服务器会被阻塞,因为它正在仔细检查一些计算成本很高的东西,或者可能正在执行一些同步IO(例如,写入sqlite数据库)。最好用一个例子来描述这一点:

给定这样的服务器:

const{execSync}=require('child_process')
const express=require('express')
const app=express()
常数端口=3000
//同步(阻塞)睡眠功能
功能睡眠(ms){
execSync(`sleep${ms/1000}`)
}
app.get('/block',(请求,res)=>{
睡眠(req.query.ms)
res.send(`Process blocked for${req.query.ms}ms.`)
})
app.get('/time',(req,res)=>res.send(new Date())
app.listen(端口,()=>console.log(`Example app listening athttp://localhost:${port}`)
我可以这样阻止nodejs进程:

#阻塞服务器两秒钟
卷曲http://localhost:3000/block\?ms\=2000
当它被阻止时,尝试向服务器发出另一个请求:

curlhttp://localhost:3000/time
第二个请求将挂起,直到阻塞调用完成,然后使用预期的日期时间进行响应。我的问题是,当nodejs进程被阻塞时,请求具体发生了什么

    节点是否使用一些低级C++读取请求并将其放入队列中?这里有背压吗
  • 这里涉及unix内核吗?它知道在服务器拒绝响应时将请求放入某种队列吗
  • 这就像curl无限期地等待套接字的响应一样简单吗
  • 如果服务器被阻止,10000个新请求击中服务器,会发生什么情况?一旦服务器解锁,它们是否都将得到服务?(假设客户端和服务器之间没有负载平衡器或其他超时机制)

最后,我明白阻塞nodejs是一种不好的做法,但我不是在问最佳做法。我想了解nodejs在这里描述的压力环境下会做什么。

在操作系统中,如果主机应用程序太忙而无法立即提取,TCP堆栈会为传入的数据或连接设置一个队列,等待相应的主机应用程序提取。根据操作系统和配置,该入站队列将在某个点填满,并且尝试连接的客户端将收到错误。我不知道nodejs中有任何单独的线程将这些数据收集到自己的队列中,nodejs可能没有任何理由这样做,因为TCP堆栈已经自己实现了一个入站连接队列

如果您阻塞nodejs进程的时间足够长,足以让10000个传入请求到达,那么您将面临更大的问题,需要解决其核心的阻塞问题。Nodejs有线程、子进程和集群,所有这些都可以用来缓解阻塞计算

对于在已打开的现有TCP连接上发送的数据,存在背压(在TCP级别)。对于新的传入连接,实际上没有背压。新的传入连接被接受或不被接受。这是我们有时认为错误连接被拒绝的原因之一

此处有一些相关讨论:

节点是否使用一些低级C++读取请求并将其放入队列中?这里有背压吗

节点本身不这样做(我知道)。OS TCP堆栈有一个用于入站数据和传入连接请求的队列

这里涉及unix内核吗?它知道在服务器拒绝响应时将请求放入某种队列吗

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

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

否。如果服务器上的入站连接请求队列已满,则连接请求将被拒绝。如果队列没有满,那么只需要等待足够长的时间,等待它成功。大多数客户端库将使用某种类型的超时,并在一段时间后放弃,以防发生导致永远不会返回响应的事件

如果服务器被阻止,10000个新请求击中服务器,会发生什么情况?一旦服务器解锁,它们是否都将得到服务?(假设客户端和服务器之间没有负载平衡器或其他超时机制)

目标主机将对入站连接请求进行排队,直至达到某个限制(这取决于操作系统和配置),然后拒绝随后出现的请求


其他一些相关条款:


这些类型的文章你读得越多,你就会越发现在快速接受大量连接和防御各种类型的DOS攻击之间的权衡。看来必须平衡一下。

谢谢!这对我来说很有意义。我创建了一个客户端来向上面的服务器发送垃圾邮件,有一些有趣的发现。我可以在我的Mac上产生500到1000个并行请求的
ECONNRESET
(相当于tcp拒绝的nodejs请求)。了解tcp积压有多大,以及有多少开放插槽似乎更为重要。不过,这是个好消息,谢谢。