Langsame Anforderungen auf dem lokalen Flask-Server

86

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

Nur ein einfacher Server wie der folgende benötigt fast 5 Sekunden, um zu antworten.

from flask import Flask

app = Flask(__name__)

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

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

Irgendwelche Ideen? Oder ist der lokale Server nur so?

Meroon
quelle
Es ist nicht der lokale Server, aber es hat möglicherweise mit anderen Anwendungen zu tun, die im Hintergrund ausgeführt werden. Auf welchem ​​Betriebssystem wird dies ausgeführt?
gabeio
Ich
laufe unter
1
Es sollte nicht so lange dauern, bis Ihre Antworten vorliegen, aber ich habe vorher tatsächlich mit der Flasche herumgespielt , ohne Erfolg. Ich würde Bottlepy raten . Obwohl Sie immer noch Ihre Hintergrundprozesse überprüfen, läuft möglicherweise eine ältere Version Ihres Servers im Hintergrund, die Ihre Python übernimmt und Ihre langsamen Antworten verursacht. Es könnte auch sein, dass Ihr Browser dies in Chrome & Safari passiert.
gabeio
2
@ Meroons Antwort war richtig für mich. Anstatt die Host-Einstellungen zu ändern: Kann ich empfehlen, einfach 127.0.0.1 anstelle von localhost zu verwenden? Damit wurde das Problem gelöst, ohne die Systemkonfiguration zu ändern.
David Bernat

Antworten:

92

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

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

Unter Betriebssystemen, die IPv6 unterstützen und konfiguriert haben, wie moderne Linux-Systeme, OS X 10.4 oder höher sowie Windows Vista, können einige Browser beim Zugriff auf Ihren lokalen Server schmerzhaft langsam sein. Der Grund dafür ist, dass "localhost" manchmal so konfiguriert ist, dass es sowohl auf ipv4- als auch auf ipv6-Sockets verfügbar ist, und einige Browser zuerst versuchen, auf ipv6 und dann auf ivp4 zuzugreifen.

Das Update besteht also darin, ipv6 vom localhost zu deaktivieren, indem die folgende Zeile aus meiner Hosts-Datei auskommentiert wird:

::1             localhost 

Sobald ich dies tue, verschwinden die Latenzprobleme.

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

Meroon
quelle
Vielen Dank! Plötzlich sind Entwicklertests bissig und reaktionsschnell! Meine einzige Frage: Da die Mac-Hosts-Datei angibt, dass das Entfernen von localhost den Betrieb meines Mac beeinträchtigen könnte, frage ich mich, ob es sich um diese Zeile handelt (oder um die Zeile, in der localhost einfach unter 127.0.0.1
David B. vom
Auf meinem Windows 10-System in der Hosts-Datei sind beide Einträge (ip4 und ip6) auskommentiert. Sie werden vom DNS-System aufgelöst. Ich habe eine enorme Geschwindigkeitssteigerung erhalten, als ich den Server auf "127.0.0.1" anstelle von "localhost" ausgeführt habe (von 2,0 auf 0,003 Sekunden für einfache Anrufe)
Lars
87

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

Beispielsweise: app.run(host="0.0.0.0", port=8080, threaded=True)

Die IPv6-Deaktivierungslösung hat bei mir nicht funktioniert, aber das hat funktioniert.

Sajid Siddiqi
quelle
5
Die Weitergabe --threadedan meine manage.pyVerwendung hat auch Flask-Scriptfunktioniert.
Snorfalorpagus
7
Für diejenigen, die es durch Aktivieren von Threads "reparieren" lassen, seien Sie gewarnt! In diesem Fall wurde die Verzögerung dadurch verursacht, dass die vorherige Anforderung nicht ordnungsgemäß geschlossen wurde. Jetzt werden nur noch viele Threads gestapelt .
kbtz
Vielen Dank, Sir, dass Sie meinen lokalen Host blitzschnell zum Laufen gebracht haben.
Benjamin
@snolflake: Gibt es eine Möglichkeit festzustellen, ob die Anforderungen nicht ordnungsgemäß geschlossen werden?
Kylotan
1
Über die Kommandozeile habe ich verwendet, flask run --with-threadswas mein Problem gelöst hat.
arno_v
13

Die Lösung von @ sajid-siddiqi ist technisch korrekt, aber denken Sie daran, dass der in Werkzeug integrierte WSGI- Server (der in Flask gepackt ist und wofür er verwendet wird)app.run() ) nur Single-Threaded ist.

Installieren Sie einen WSGI- Server, um Multithread-Verhalten verarbeiten zu können. Ich habe eine Reihe von Recherchen zu verschiedenen WSGI- Serverleistungen durchgeführt. Ihre Anforderungen können variieren, aber wenn Sie nur Flask verwenden , würde ich einen der folgenden Webserver empfehlen.

Update (2020-07-25): Es sieht so aus, als ob gevent vor 5 Jahren mit der Unterstützung von python3 begonnen hat, kurz nachdem ich kommentiert habe, dass dies nicht der Fall ist , sodass Sie gevent jetzt verwenden können.

gevent

Sie können gevent über pip mit dem Befehl pip install geventoder pip3 mit dem Befehl installieren pip3 install gevent. Anweisungen zum entsprechenden Ändern Ihres Codes finden Sie hier: https://flask.palletsprojects.com/de/1.1.x/deploying/wsgi-standalone/#gevent

meinheld

gevent ist besser, aber von allen Benchmarks, die ich mir angesehen habe und die reale Tests beinhalten, scheint meinheld der einfachste und einfachste WSGI- Server zu sein. (Sie können sich auch uWSGI ansehen, wenn Ihnen die Konfiguration nichts ausmacht.)

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

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

mikeho
quelle
Ich hatte große Leistungsprobleme mit Flask, selbst die einfachsten Anfragen dauerten ungefähr 0,5 Sekunden. Einfach auf gevent umgestellt und alles funktioniert einwandfrei, danke!
Gronostaj
7

Mein Problem wurde durch "threaded = True" gelöst, aber ich möchte einige Hintergrundinformationen geben, um mein Problem von anderen zu unterscheiden, für die dies möglicherweise nicht der Fall ist.

  1. Mein Problem trat nur auf, wenn Flask mit python3 ausgeführt wurde. Beim Wechsel zu Python2 hatte ich dieses Problem nicht mehr.
  2. Mein Problem trat nur beim Zugriff auf die API mit Chrome auf. Zu diesem Zeitpunkt zeigte Chrome den erwarteten Bildschirm an, aber alles andere blieb hängen (Curl, ffx usw.), bis ich den Chrome-Tab entweder neu lud oder schloss. Zu diesem Zeitpunkt wartete alles andere herum gab ein Ergebnis zurück.

Ich vermute, dass Chrome versucht hat, die Sitzung offen zu halten, und Flask die nachfolgenden Anforderungen blockiert hat. Sobald die Verbindung von Chrome gestoppt oder zurückgesetzt wurde, wurde alles andere verarbeitet.

In meinem Fall wurde das Threading behoben. Natürlich gehe ich jetzt einige der Links durch, die andere bereitgestellt haben, um sicherzustellen, dass keine anderen Probleme auftreten.

ChePazzo
quelle
6

Anstatt http://localhost:port/endpointanzurufen http://127.0.0.1:port/endpoint. Dies beseitigte die anfängliche Verzögerung von 500 ms für mich.

LangeTreeDorpie
quelle
Für mich wurden ungefähr 3 Sekunden entfernt (ich habe von 0.0.0.0 auf 127.0.0.1 verschoben). Kann jemand erklären, warum und wie es funktioniert?
Rotkiv
Warum in Gottes Namen funktioniert das? Ging von 2,06 Sekunden auf 0,002 Sekunden. Der Browser kann localhost problemlos verwenden, die Auflösung von request.get auf localhost dauert jedoch 2 Sekunden.
Xevion
4

threaded=Truefunktioniert für mich, aber schließlich habe ich herausgefunden, dass das Problem auf Foxyproxy auf Firefox zurückzuführen ist. Seitdem die Flask-App auf localhost ausgeführt wird, erfolgt eine langsame Reaktion, wenn

  • Foxyproxy ist auf Firefox aktiviert

langsame Reaktion 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. Ich habe versucht, localhost zur Proxy-Blacklist hinzuzufügen und die Einstellungen zu optimieren, aber keine davon hat funktioniert.

Edward
quelle
2

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

::1 localhostwurde bereits in meiner Hosts-Datei auskommentiert, und die Einstellung Threaded=truehat bei mir nicht funktioniert. Die Verarbeitung jeder REST-Anforderung dauerte 1 Sekunde, anstatt sofort zu erfolgen.

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

Um gevent zu verwenden, installieren Sie es mit pip install gevent

Danach habe ich https://gist.github.com/viksit/b6733fe1afdf5bb84a40#file-async_flask-py-L41 verwendet , um den Kolben für die Verwendung von gevent einzustellen.

Wenn der Link ausfällt, sind hier 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 __name__ == '__main__':
    main()
Ali Mizan
quelle
threaded = True funktioniert nicht für (mit Python 3.6.7 und Postman), ich erhalte VersionConflict: (Greenlet 0.4.13 (c: \ anaconda3 \ lib \ site-packages), Requirement.parse ('greenlet> = 0.4. 14; platform_python_implementation == "CPython" ')), darf ich wissen, wie man das
löst?
0

Ich habe diesen Fehler erhalten, wenn ich auf anderen Hosts localhostals auch ausgeführt habe, sodass bei einigen zugrunde liegenden Problemen dieselben Symptome auftreten können.

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

(Auch eine verwandte Frage: Kolben-App hängt gelegentlich )

gatoatigrado
quelle
0

Ich hatte hier eine andere Lösung. Ich habe gerade alles .pycaus dem Serververzeichnis gelöscht und es erneut gestartet. Localhost wurde übrigens bereits in meiner Hosts-Datei (Windows 8) auskommentiert.

Der Server hat die ganze Zeit eingefroren und jetzt funktioniert es wieder einwandfrei.

erickrf
quelle