2015-04-15 5 views
5

Ich habe eine einfache Testanwendung auf Windows - Tornado läuft eine Flask wsgi-Anwendung. Ich kann den Server gut starten und durch meinen Webbrowser verbinden und das ist einfach cool.Warum verschluckt und stirbt mein Tornado/Flask-Server unter Windows, wenn er ihn mit Anfragen hämmert?

Ich kann meinen Leistungstest ausführen, und auf meinem Rechner bekomme ich ~ 900-1000 Anfragen pro Sekunde. Nach ungefähr 20.000 Anforderungen reagiert mein Server jedoch nicht mehr und mein Test meldet 0 pro Sekunde. Ich kann versuchen, über den Webbrowser eine Verbindung herzustellen, aber nichts. Typischerweise ctrl + c hat auch einige Probleme (mehrere Male zu treffen, bevor die Seite im Browser aktualisiert wird, wird der Server wie normalerweise beendet).

Warum also würgt mein Server und stirbt, wenn ich ihn so hämmere?

Okay, also versuchte ich, verschiedene Faktoren auszuschließen - ich konnte den Server von einer anderen Maschine aus starten, obwohl mein lokaler Rechner gerade schnorchelte, also sieht es so aus, als ob mein lokaler Rechner ausgeht Ports oder etwas?

Wie auch immer, hier ist mein Code:

server.py

from flask import Flask 

app = Flask(__name__) 


@app.route("/") 
def main(): 
    return "Hey, it's working" 


if __name__ == "__main__": 
    app.run("0.0.0.0", port=5000, debug=True) 

tornado_server.py

from tornado.wsgi import WSGIContainer 
from tornado.httpserver import HTTPServer 
from tornado.ioloop import IOLoop 
from server import app 

http_server = HTTPServer(WSGIContainer(app)) 
http_server.listen(5000) 
IOLoop.instance().start() 

perftest.py

from socket import * 
import time 

n = 0 
stop = False 

from threading import Thread 
def monitor(): 
    global n, stop 
    while not stop: 
     time.sleep(1) 
     print(n, 'reqs/sec') 
     n = 0 


if __name__ == "__main__": 
    t = Thread(target=monitor).start() 
    while True: 
     try: 
      sock = socket(AF_INET, SOCK_STREAM) 
      sock.connect(('localhost', 5000)) 
      sock.send(b'''GET/HTTP/1.1\n\n''') 
      resp = sock.recv(4096) 
      sock.close() 
      n += 1 
     except KeyboardInterrupt: 
      stop = True 
     except: 
      pass 
+0

Ich weiß *, dass der Titel wahrscheinlich ein bisschen irreführend ist, da ich jetzt weiß, dass es nicht Flask/Tornado mit dem Problem ist. Aber ich denke, wenn jemand ein ähnliches Problem hat, dann wird dieser Titel hilfreicher darin sein, sie zu zeichnen, damit sie sehen können: "Überraschung! Das Problem ist wahrscheinlich nicht wo du dachtest" –

+0

Sieht aus wie Beazleys Code. –

+0

@AshwiniChaudhary Gutes Auge - sah gerade Teil seiner Rede letzte Nacht einschlafen, und es passierte perfektes Timing. Natürlich benutzte er einen Mac in der Demo, also keine Probleme. Ich habe gerade meinen Perftest auf eine Linux-Box geworfen und meinen Server gehämmert, aber keine Socket-Probleme. Ging viel langsamer, da es nicht lokal war. Und jetzt, wo ich darüber nachdenke, habe ich statt der IP-Adresse eine DNS-Lösung gemacht. Es sieht also so aus, als ob das Problem mit Windows Sockets zu tun hat. Ich bin nicht überrascht: P –

Antwort

1

Ich schätze, Sie haben keine Ports mehr. Jede Verbindung, die Sie erstellen, blockiert einen Port und es dauert einige Zeit, sie zu schließen, unter Windows länger als auf anderen Betriebssystemen. Als Symptom sollte nach einiger Zeit, aber nur in Kürze, arbeiten.

Sie können das mit netstat überprüfen.

+1

Sieht aus wie das der Fall ist - Netstat zeigt eine Tonne von Ports in 'TIME_WAIT'. Warum sollte der Aufruf "sock.close()" die Sockets nicht ausschalten? Ich habe ein 'e' hinzugefügt, um Fehler zu zählen, und bis sie aufhören zu verbinden, sehe ich keine Fehler. –

+0

Wird die 'socket.SO_REUSEADDR' Option in diesem Fall helfen? –

Verwandte Themen