2016-03-06 45 views
15

把这个代码,我添加了一个HTTP服务器的典型节点JS例如5秒的延迟,以模拟一些异步工作正在进行别处:为什么setTimeout会阻止我的Node.js应用程序?

const http = require('http'); 

const hostname = '127.0.0.1'; 
const port = 8080; 

http.createServer((req, res) => { 
    setTimeout(()=>{ 
     res.writeHead(200, { 'Content-Type': 'text/plain' }); 
     res.end('Hello World\n'); 
    },5000); 
}).listen(port, hostname,() => { 
    console.log(`Server running at http://${hostname}:${port}/`); 
}); 

我会想到的是,当我打开5个标签页,让我们有半秒的打开每个之间的延迟说,服务器应该“响应”每个标签或多或少与此计时:

t=0s - I open first tab 
t=0.5s - I open second tab 
t=1s - I open third tab 
... 
t=5s - First tab stops loading, server has replied 
t=5.5s - Second tab stops loading, server has replied 
t=6s - Third tab stops loading, server has replied 
t=6.5s - Fourth tab stops loading, server has replied 
t=7s - Fifth tab stops loading, server has replied 

不过,我看到的行为是如下:

t=0s - I open first tab 
t=0.5s - I open second tab 
t=1s - I open third tab 
... 
t=5s - First tab stops loading, server has replied 
t=10s - Second tab stops loading, server has replied 
t=15s - Third tab stops loading, server has replied 
t=20s - Fourth tab stops loading, server has replied 
t=25s - Fifth tab stops loading, server has replied 

好像后续请求在第一个请求完成之前还没有开始运行。我在这里错过了什么吗?我认为Node JS的全部重点是能够从单个线程运行异步启动?

+1

仅供参考,您还需要注意浏览器喜欢制作的favicon请求以及页面请求,这也会使问题复杂化。 – jfriend00

回答

17

问题不在于您的代码或Node.js - 这是您如何设置测试。

您错误地认为您的浏览器会发出5个并发请求,这不会发生。不同的浏览器具有不同的行为,但通常浏览器将数量限制在一个非常低的数量,即同时连接到单个来源的最大数量。 HTTP规范给出了最大的建议。 我真的很惊讶,看到Chrome只打开一个单一的连接到本地主机,因为我知道Chrome打开6到其他来源 - 刚刚学到了一些新的东西!

使用其他工具来运行您的测试,您可以控制它并确定它正在发出并发请求。然后你会看到预期的行为。

作为一个例子,我运行了你的代码并用Apache Benchmark进行了测试,如下所示。参数指示:-n 10是发出10个请求,-c 10是使用并发10(即,使所有10个请求同时发生)。正如你可以在下面的结果看,采取所有请求的总时间为5秒〜(和“每个要求时间”为0.5s):

~ $ ab -n 10 -c 10 http://127.0.0.1:8080/ 
This is ApacheBench, Version 2.3 <$Revision: 1663405 $> 
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ 
Licensed to The Apache Software Foundation, http://www.apache.org/ 

Benchmarking 127.0.0.1 (be patient).....done 


Server Software: 
Server Hostname:  127.0.0.1 
Server Port:   8080 

Document Path:  /
Document Length:  12 bytes 

Concurrency Level:  10 
Time taken for tests: 5.019 seconds 
Complete requests:  10 
Failed requests:  0 
Total transferred:  1130 bytes 
HTML transferred:  120 bytes 
Requests per second: 1.99 [#/sec] (mean) 
Time per request:  5019.151 [ms] (mean) 
Time per request:  501.915 [ms] (mean, across all concurrent requests) 
Transfer rate:   0.22 [Kbytes/sec] received 

Connection Times (ms) 
       min mean[+/-sd] median max 
Connect:  0 0 0.1  0  0 
Processing: 5017 5018 0.3 5018 5018 
Waiting:  5008 5008 0.2 5008 5009 
Total:  5018 5018 0.2 5019 5019 
ERROR: The median and mean for the total time are more than twice the standard 
     deviation apart. These results are NOT reliable. 

Percentage of the requests served within a certain time (ms) 
    50% 5019 
    66% 5019 
    75% 5019 
    80% 5019 
    90% 5019 
    95% 5019 
    98% 5019 
    99% 5019 
100% 5019 (longest request) 
+4

OP还可以在Chrome调试器的网络选项卡中查看请求实际发送到服务器的时间。调试器的网络选项卡中的时间线将告诉整个故事。 – jfriend00

+0

你是非常正确的先生,试着让Chrome,Firefox和边并排,并刷新每个浏览器的页面,我得到了预期的结果! 也感谢您花时间测试它并发布结果! 王牌答案,这就是为什么我活着:) :) –

+0

@ jfriend00没错,它甚至没有跨过我的脑海,我会成为一个浏览器问题! –

5

似乎这只是发生在某些浏览器,我试图与野生动物园,并按预期工作。 所以我想Chrome会同时限制同一个资源的请求数量

+0

Firefox也在做它(阻止连接到同一主机的连接数) –

+0

@RubenSerrate你是对的 – wong2

相关问题