wake-up-neo.com

Langsame Anfragen auf lokalem Flask Server

Ich fange gerade damit an, mit Flask auf einem lokalen Server herumzuspielen, und ich merke, dass die Anforderungs-/Antwortzeiten viel langsamer sind, als ich denke, dass sie sein sollten.

Ein einfacher Server wie der folgende benötigt etwa 5 Sekunden, um zu antworten.

from flask import Flask

app = Flask(__name__)

@app.route("/")
def index():
    return "index"

if __== "__main__":
    app.run()

Irgendwelche Ideen? Oder ist dies nur der lokale Server?

66
Meroon

Ok, ich habe es herausgefunden. Es scheint ein Problem mit Werkzeug und Betriebssystemen zu sein, die ipv6 unterstützen.

Von der Werkzeug-Site http://werkzeug.pocoo.org/docs/serving/ :

Auf Betriebssystemen, die IPv6 unterstützen und wie Linux-Systeme, OS X 10.4 oder höher sowie Windows Vista konfiguriert haben, können einige Browser beim Zugriff auf Ihren lokalen Server sehr langsam sein. Der Grund dafür ist, dass manchmal „localhost“ so konfiguriert ist, dass es sowohl für ipv4- als auch für ipv6-socktes verfügbar ist. 

Die Lösung besteht also darin, ipv6 vom localhost zu deaktivieren, indem Sie die folgende Zeile aus meiner hosts-Datei auskommentieren:

::1             localhost 

Sobald ich dies tue, verschwinden die Latenzprobleme.

Ich grabe Flask wirklich und bin froh, dass es mit dem Framework kein Problem ist. Ich wusste, dass es nicht sein konnte.

80
Meroon

Fügen Sie "thread = True" als Argument zu app.run () hinzu, wie hier vorgeschlagen: http://arusahni.net/blog/2013/10/flask-multithreading.html

Zum Beispiel: app.run(Host="0.0.0.0", port=8080, threaded=True)

Die IPv6-Deaktivierungslösung hat für mich nicht funktioniert, aber das hat funktioniert. 

74
Sajid Siddiqi

Die Lösung von @ sajid-siddiqi ist technisch korrekt, bedenken Sie jedoch, dass der eingebaute WSGI Server in Werkzeug (der in Flask verpackt ist und was er verwendet für app.run()).

Installieren Sie einen WSGI-Server, um mit Multithread-Verhalten umgehen zu können. Ich habe ein paar Recherchen zu verschiedenen WSGI Server-Performances durchgeführt. Ihre Bedürfnisse können variieren, aber wenn Sie nur Flask verwenden, würde ich einen der folgenden Webserver empfehlen.

Für Python 2.x: gevent

Sie können gevent über pip mit dem Befehl pip install gevent installieren. Anweisungen zum Ändern des Codes finden Sie hier: http://flask.pocoo.org/docs/0.10/deploying/wsgi-standalone/#gevent

Für Python 3.x: meinheld

gevent ist besser, aber es wurde noch nicht aktualisiert, um python3 zu verwenden (siehe diesen Thread für Updates: https://github.com/gevent/gevent/issues/38 ). Von all den Benchmarks, die ich mir bei realistischen Tests angesehen habe, scheint meinheld der einfachste und einfachste WSGI Server zu sein. (Sie können sich auch uWSGI ansehen, wenn Sie sich nicht für weitere Konfigurationen interessieren.)

Sie können meinheld auch über pip3 mit dem Befehl pip3 install meinheld installieren. Sehen Sie sich das Beispiel in der Quelle meinheld an, um Flask: https://github.com/mopemope/meinheld/blob/master/example/flask_sample.py zu integrieren.

* HINWEIS: Bei meiner Verwendung von PyCharm wird die Zeile from meinheld import server als Fehler hervorgehoben. Der Server wird jedoch ausgeführt, sodass Sie den Fehler ignorieren können.

6
mikeho

Ich habe nicht den ganzen Ruf, einen Kommentar abzugeben, also füge ich dies als "Lösung" hinzu. Mein Problem wurde durch "Thread = True" gelöst, aber ich möchte etwas Hintergrundwissen geben, um mein Problem von anderen zu unterscheiden wofür das dies nicht tun darf.

  1. Mein Problem trat nur auf, wenn Flask mit Python3 ausgeführt wurde. Beim Umschalten auf Python2 hatte ich dieses Problem nicht mehr.
  2. Mein Problem wurde mit only beim Zugriff auf die API mit Chrome angezeigt. An diesem Punkt zeigte Chrome den erwarteten Bildschirm an, aber alles andere hing (curl, ffx usw.), bis ich entweder den Chrome-Tab neu geladen oder geschlossen habe Andernfalls gab es ein Ergebnis.

Meine beste Vermutung ist, dass Chrome versucht hat, die Sitzung offen zu halten, und Flask die nachfolgenden Anforderungen blockierte. Sobald die Verbindung von Chrome unterbrochen oder zurückgesetzt wurde, wurde alles andere verarbeitet.

In meinem Fall wurde es durch Einfädeln behoben. Natürlich gehe ich jetzt auf einige der Links, die andere zur Verfügung gestellt haben, um sicherzustellen, dass dadurch keine anderen Probleme entstehen.

5
ChePazzo

threaded=True funktioniert für mich, aber schließlich habe ich herausgefunden, dass das Problem auf foxyproxy von Firefox zurückzuführen ist. Wenn die Flaschen-App auf localhost ausgeführt wird, erfolgt eine langsame Antwort, wenn

  • foxyproxy ist auf Firefox aktiviert

langsame Antwort wird nicht passieren, wenn

  • foxyproxy ist auf Firefox deaktiviert

  • greifen Sie mit anderen Browsern auf die Website zu

Die einzige Lösung, die ich gefunden habe, ist das Deaktivieren von Foxyproxy. Es wurde versucht, localhost zu Proxy-Blacklist- und Tweak-Einstellungen hinzuzufügen.

3
edward

Ich habe diese Fehlermeldung erhalten, wenn ich auf anderen Hosts als localhost laufe, daher können bei einigen zugrunde liegenden Problemen dieselben Symptome auftreten.

Ich habe die meisten Dinge, die ich benutzt habe, auf Tornado umgestellt, und anekdotisch hat es eine Menge geholfen. Ich hatte ein paar langsame Seitenladevorgänge, aber die Dinge scheinen im Allgemeinen besser zu reagieren. Auch sehr anekdotisch, aber ich scheine zu bemerken, dass Flask allein mit der Zeit langsamer wird, aber Flask + Tornado weniger. Ich stelle mir vor, Apache und mod_wsgi würden die Dinge noch besser machen, aber Tornado ist wirklich einfach einzurichten (siehe http://flask.pocoo.org/docs/deploying/others/ ).

(Auch eine verwandte Frage: Flask App gelegentlich hängen )

0
gatoatigrado

Ich hatte hier eine andere Lösung. Ich habe gerade alles .pyc aus dem Serververzeichnis gelöscht und neu gestartet.

Der Server fror die ganze Zeit ein und jetzt funktioniert es wieder einwandfrei.

0
erickrf

Ich habe Mihekos Antwort benutzt, um mein Problem zu lösen.

::1 localhost wurde in meiner Hosts-Datei bereits auskommentiert, und das Festlegen von Threaded=true hat bei mir nicht funktioniert. Für jede REST Anforderung wurde 1 Sekunde benötigt, um sie zu verarbeiten, anstatt sie sofort auszuführen.

Ich verwende Python 3.6 und habe flask dazu gebracht, schnell auf REST Anfragen zu reagieren, indem flask gevent als WSGI verwendet.

Um gevent zu benutzen, installiere es mit pip install gevent

Danach habe ich mit https://Gist.github.com/viksit/b6733fe1afdf5bb84a40#file-async_flask-py-L41 festgelegt, dass der Kolben gevent verwendet.

Wenn der Link ausfällt, hier sind die wichtigen Teile des Skripts:

from flask import Flask, Response
from gevent.pywsgi import WSGIServer
from gevent import monkey

# need to patch sockets to make requests async
# you may also need to call this before importing other packages that setup ssl
monkey.patch_all()

app = Flask(__name__) 


# define some REST endpoints... 

def main():

    # use gevent WSGI server instead of the Flask
    # instead of 5000, you can define whatever port you want.
    http = WSGIServer(('', 5000), app.wsgi_app) 

    # Serve your application
    http.serve_forever()


if __== '__main__':
    main()
0
Ali Mizan