Kann ich mehrere Clients nur mit Flask app.run () als Standalone bedienen?

201

Ich weiß, dass ich Flask mit Apache oder anderen Webservern verbinden kann. Ich dachte jedoch daran, Flask als eigenständigen Server auszuführen, der mehrere Clients gleichzeitig bedient.

Ist das möglich? Muss ich mehrere Threads erzeugen und verwalten?

ATOzTOA
quelle

Antworten:

295

flask.Flask.runakzeptiert zusätzliche Schlüsselwortargumente ( **options), an die weitergeleitet wird werkzeug.serving.run_simple- zwei dieser Argumente sind threaded(ein Boolescher Wert) undprocesses Wert (die Sie auf eine Zahl größer als eins setzen können, damit werkzeug mehr als einen Prozess zur Bearbeitung von Anforderungen erzeugt).

threadedStandardwerte Truewie von Flask 1.0, so dass für die neuesten Versionen von Flask, wird die Standard - Entwicklungs - Server mehrere Clients gleichzeitig standardmäßig dienen können. Bei älteren Versionen von Flask können Sie explizit übergeben threaded=True, um dieses Verhalten zu aktivieren.

Zum Beispiel können Sie tun

if __name__ == '__main__':
    app.run(threaded=True)

um mehrere Clients mithilfe von Threads auf eine Weise zu behandeln, die mit alten Flask-Versionen kompatibel ist, oder

if __name__ == '__main__':
    app.run(threaded=False, processes=3)

Werkzeug anzuweisen, drei Prozesse zu erzeugen, um eingehende Anfragen zu verarbeiten, oder einfach

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

um mehrere Clients mithilfe von Threads zu behandeln, wenn Sie wissen, dass Sie Flask 1.0 oder höher verwenden werden.

Davon abgesehen serving.run_simpleverpackt Werkzeug's das wsgirefPaket der Standardbibliothek - und dieses Paket enthält eine Referenzimplementierung von WSGI, keinen produktionsbereiten Webserver. Wenn Sie Flask in der Produktion verwenden möchten (vorausgesetzt, "Produktion" ist keine verkehrsarme interne Anwendung mit nicht mehr als 10 gleichzeitigen Benutzern), stellen Sie sicher, dass Sie sie hinter einem echten Webserver aufstellen (siehe den Abschnitt in den Dokumenten von Flask mit dem Titel) Bereitstellungsoptionen für einige vorgeschlagene Methoden).

Sean Vieira
quelle
2
Was ist, wenn ich maximal 100 Benutzer betrachte? Kann ich einfach zuweisen processes=100und damit zufrieden sein? In meinem Fall benötige ich nur statische Dateien, keine HTTP-Post-Methoden. Meine Anforderung ist, dass ich alle Flask-Threads als Teil meiner übergeordneten App ausführen möchte, damit sie alle Variablen gemeinsam nutzen können.
ATOzTOA
4
Chuckles - @ATOzTOA - nein, das wäre wahrscheinlich ziemlich kontraproduktiv (Prozesse sind relativ teuer, und wenn Sie nicht bei jeder Anfrage viel arbeiten, gibt es keinen Grund, warum 4 oder 8 Prozesse nicht ausreichen sollten). Wenn Sie jedoch nur statischen Inhalt anzeigen, ist ein Server, der dafür optimiert ist (Apache, ngnix, IIS), besser geeignet.
Sean Vieira
2
Außerdem sollten Sie normalerweise keine Variablen über Anforderungen hinweg gemeinsam nutzen müssen. In diesem Fall müssen Sie sich entweder auf einen Prozess beschränken oder eine Out-of-Band-Kommunikation (Redis, eine Datenbank, das Dateisystem usw.) verwenden dass jeder Ihrer Prozesse synchron bleibt.
Sean Vieira
3
@ATOzTOA - Wenn Sie keinen besseren Server hochfahren können, würde ich ihn einfach ausprobieren und sehen, was passiert. Wenn es unter Last nicht gut funktioniert, können Sie es hinter einem anderen Webserver bereitstellen.
Sean Vieira
2
@ATOzTOA, zu Ihrer Frage, warum Sie nicht gleichzeitig "Threaded" und "Prozesse" angeben können, siehe den Code hier: werkzeug.readthedocs.org/en/latest/_modules/werkzeug/serving
pyrho
62

Durch die Verwendung von simple app.run()from Flask wird ein einzelner synchroner Server auf einem einzelnen Thread erstellt, der jeweils nur einen Client bedienen kann. Genau aus diesem Grund ist es für den Einsatz in kontrollierten Umgebungen mit geringer Nachfrage (dh Entwicklung, Debugging) vorgesehen.

Das Laichen und Verwalten von Threads wird Sie aufgrund der Python-GIL wahrscheinlich auch nicht sehr weit bringen .

Trotzdem haben Sie noch einige gute Möglichkeiten. Gunicorn ist ein solider, benutzerfreundlicher WSGI-Server, mit dem Sie mehrere Worker erzeugen können (separate Prozesse, also keine GIL-Sorgen), und der sogar mit asynchronen Workern geliefert wird , die Ihre App mit wenig beschleunigen (und sicherer machen) zu keiner Arbeit von Ihrer Seite (besonders mit Flask).

Dennoch sollte selbst Gunicorn wahrscheinlich nicht direkt öffentlich ausgesetzt werden. In der Produktion sollte es hinter einem robusteren HTTP-Server verwendet werden. nginx neigt dazu , mit Gunicorn und Kolben gut zu gehen.

Ryan Artecona
quelle
17
nicht ganz. Gunicorn ist Python, Nginx nicht. so würdest du sie aber nicht benutzen. Mit Gunicorn können Sie Ihre App als gunicorn app:app 127.0.0.1:8080statt ausführen python app.py. Nginx fungiert als öffentlicher Dienst, der Ihre private, von Gunicorn ausgeführte App (einen Reverse-Proxy) verfügbar macht und alle möglichen Details der HTTP-Implementierung auf niedrigerer Ebene
verbirgt
Flask mit app.run (threaded = True) läuft auf Apache2 sehr gut mit mod_wsgi flask.palletsprojects.com/de/1.1.x/deploying/mod_wsgi
MortenB