2016-03-06 13 views
15

Nehmen Sie diesen Code, typischen Knoten js Beispiel eines Http-Server, auf denen habe ich eine Verzögerung von 5 Sekunden zugegeben woanders etwas async Arbeit statt zu simulieren:Warum blockiert setTimeout meine Node.js App?

Ich erwarte, dass
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}/`); 
}); 

Was würde ist, dass, wenn ich öffne 5 Registerkarten, sagen sie mal mit einer Verzögerung von einer halben Sekunde zwischen jeder Öffnung der Server sollte „reagieren“ zu jedem Reiter mehr oder weniger mit diesen Timings:

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 

jedoch das Verhalten ich sehe ist die folgenden:

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 

Als würden die nachfolgenden Anfragen nicht gestartet, bis der erste fertig ist. Fehle ich hier etwas? Ich dachte, der ganze Sinn von Node JS wäre, asynchrone Aufgaben aus einem einzigen Thread ausführen zu können?

+1

FYI, müssen Sie auch für Favicon Anfragen, die Browser zusammen mit einer Seitenanforderung, die auch die Dinge komplizieren können, machen aufpassen . – jfriend00

Antwort

17

Das Problem ist nicht Ihr Code oder Node.js - so richten Sie Ihren Test ein.

Sie haben fälschlicherweise angenommen, dass Ihr Browser 5 gleichzeitige Anfragen machen würde, was nicht geschieht. Verschiedene Browser haben unterschiedliche Verhaltensweisen, aber in der Regel begrenzen Browser die Anzahl der gleichzeitigen Verbindungen zu einem einzelnen Ursprung auf eine sehr niedrige Anzahl. Die HTTP-Spezifikation gibt einen maximalen Vorschlag. Ich war eigentlich ziemlich überrascht zu sehen, dass Chrome nur 1 einzige Verbindung zu localhost eröffnet, da ich weiß, dass Chrome 6 zu anderen Ursprüngen öffnet - gerade etwas Neues gelernt!

Verwenden Sie ein anderes Tool, um Ihren Test auszuführen, einen, den Sie steuern können und der sicher ist, dass er gleichzeitige Anfragen erstellt. Dann sehen Sie das erwartete Verhalten.

Als Beispiel führte ich Ihren Code und getestet mit Apache Benchmark wie unten gezeigt. Die Parameter zeigen an: -n 10 soll 10 Anfragen machen, -c 10 soll Nebenläufigkeit 10 benutzen (dh alle zehn Anfragen gleichzeitig machen). Wie Sie unten in den Ergebnissen sehen kann, war die Gesamtzeit für alle Anfragen genommen ~ 5s (und „Zeit pro Anfrage“ 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

Das OP kann auch auf der Netzwerkregisterkarte des Chrome-Debuggers nachsehen, wann die Anfragen tatsächlich an den Server gesendet werden. Die Timeline in der Netzwerk-Registerkarte des Debuggers dort wird die ganze Geschichte erzählen. – jfriend00

+0

Sie sind sehr richtig Herr, versucht, Chrom, Firefox und Kante nebeneinander und die Seite auf jedem Browser aktualisieren, und ich habe die erwarteten Ergebnisse !! Danke auch, dass Sie sich die Zeit genommen haben, es zu testen und Ergebnisse zu posten! Ace Antwort, deshalb lebe ich SO :) –

+0

@ jfriend00 Ja, es ist mir nicht einmal in den Sinn gekommen, dass ich ein Browserproblem wäre! –

5

scheint dies nur in einigen Browsern geschieht, habe ich versucht, mit Safari und es funktioniert wie erwartet. Also schätze ich, dass Chrome würde die Anzahl der gleichen Anfragen auf die gleiche Ressource zur gleichen Zeit

+0

Firefox tut es auch (die Anzahl der Verbindungen zu dem gleichen Host blockiert) –

+0

@RubenSerrate du hast Recht – wong2

Verwandte Themen