Richieste lente sul server Flask locale


87

Ho appena iniziato a giocare con Flask su un server locale e sto notando che i tempi di richiesta / risposta sono molto più lenti di quanto ritengo dovrebbero essere.

Solo un semplice server come il seguente impiega circa 5 secondi per rispondere.

from flask import Flask

app = Flask(__name__)

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

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

Qualche idea? O è così che è il server locale?


Non è il server locale ma potrebbe avere a che fare con altre applicazioni in esecuzione in background su quale sistema operativo lo stai eseguendo?
gabeio

Sto eseguendo OS X 10.7 su un iMac i7
Meroon

1
Non dovrebbe impiegare così tanto tempo per le tue risposte, ma in realtà ho scherzato con la fiaschetta prima che senza successo consiglierei Bottlepy . Sebbene continui a controllare i processi in background, potresti avere una versione precedente del tuo server in esecuzione in background che prende il controllo del tuo python e causa le tue risposte lente. Inoltre potrebbe essere il tuo browser, questo accade in Chrome e Safari?
gabeio

2
La risposta di @ Meroon era corretta per me. Invece di modificare le impostazioni dell'host, tuttavia: potrei raccomandare semplicemente di utilizzare 127.0.0.1 invece di localhost? Ciò ha risolto il problema senza modificare la configurazione del sistema.
David Bernat

Risposte:


94

Ok ho capito. Sembra essere un problema con Werkzeug e sistemi operativi che supportano ipv6.

Dal sito Werkzeug http://werkzeug.pocoo.org/docs/serving/ :

Sui sistemi operativi che supportano ipv6 e lo hanno configurato come i moderni sistemi Linux, OS X 10.4 o versioni successive e Windows Vista, alcuni browser possono essere estremamente lenti se si accede al server locale. La ragione di ciò è che a volte "localhost" è configurato per essere disponibile su entrambi i sockte ipv4 e ipv6 e alcuni browser proveranno ad accedere prima a ipv6 e poi a ivp4.

Quindi la soluzione è disabilitare ipv6 da localhost commentando la seguente riga dal mio file hosts:

::1             localhost 

Una volta fatto questo, i problemi di latenza scompaiono.

Sto davvero scavando su Flask e sono contento che non sia un problema con il framework. Sapevo che non poteva essere.



molte grazie! improvvisamente il test di sviluppo è scattante e reattivo! la mia unica domanda: poiché il file hosts del Mac indica che la rimozione di localhost potrebbe influire sulle operazioni del mio Mac, mi chiedo se si riferisca a questa riga (o quella che individua semplicemente localhost su 127.0.0.1
David B.

sul mio sistema Windows 10 nel file hosts entrambe le voci (ip4 e ip6) sono commentate; vengono risolti dal sistema DNS. Ho ottenuto un enorme aumento di velocità quando ho eseguito il server su "127.0.0.1" invece di "localhost" (da 2.0 a 0.003 secondi per chiamate semplici)
Lars

Grazie per questa risposta! Sebbene la mia situazione fosse un po 'diversa (correre nose2 contro aiosmtpd), la tua risposta mi ha dato un suggerimento: quando disabilito IPv6 sul mio laptop Windows 10 accelera cose come 10x o 100x !!
pepoluan

91

Aggiungi "threaded = True" come argomento a app.run (), come suggerito qui: http://arusahni.net/blog/2013/10/flask-multithreading.html

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

La soluzione di disabilitazione di ipv6 non ha funzionato per me, ma ha funzionato.


5
Anche il passaggio --threadedal mio manage.pyutilizzo ha Flask-Scriptfunzionato.
Snorfalorpagus

7
Per coloro che ottengono "riparato" abilitando i thread, fate attenzione! In questo caso il ritardo è stato causato dal fatto che la richiesta precedente non è stata chiusa correttamente, quindi ora si tratta solo di impilare molti thread .
kbtz

1
Grazie signore per aver reso il mio host locale incredibilmente veloce.
benjaminz

@snolflake: c'è un modo per sapere se le richieste non vengono chiuse correttamente?
Kylotan

1
Dalla riga di comando che ho usato ha flask run --with-threadsrisolto il mio problema.
arno_v

13

La soluzione da @ sajid-siddiqi è tecnicamente corretta, ma tieni presente che il server WSGI integrato in Werkzeug (che è impacchettato in Flask e per cosa usa app.run()) è solo a thread singolo.

Installa un server WSGI per poter gestire il comportamento multi-thread. Ho fatto un sacco di ricerche su varie prestazioni del server WSGI . Le tue esigenze possono variare, ma se tutto ciò che stai usando è Flask , allora consiglierei uno dei seguenti server web.

Aggiornamento (2020-07-25): Sembra che gevent abbia iniziato a supportare python3 5 anni fa, poco dopo che ho commentato che non lo faceva, quindi puoi usare gevent ora.

gevent

Puoi installare gevent tramite pip con il comando pip install gevento pip3 con il comando pip3 install gevent. Le istruzioni su come modificare il codice di conseguenza sono qui: https://flask.palletsprojects.com/en/1.1.x/deploying/wsgi-standalone/#gevent

meinheld

gevent è migliore, ma da tutti i benchmark che ho esaminato che implicano test nel mondo reale, meinheld sembra essere il server WSGI più diretto e semplicistico . (Puoi anche dare un'occhiata a uWSGI se non ti dispiace un po 'di configurazione in più.)

Puoi anche installare meinheld tramite pip3 con il comando pip3 install meinheld. Da lì, guarda l'esempio fornito nel sorgente meinheld per integrare Flask : https://github.com/mopemope/meinheld/blob/master/example/flask_sample.py

* NOTA: dal mio utilizzo di PyCharm , la riga viene from meinheld import serverevidenziata come un errore, ma il server verrà eseguito, quindi puoi ignorare l'errore.


Ho avuto grossi problemi di prestazioni con Flask, anche le richieste più semplici richiedevano circa 0,5 secondi per terminare. Sono appena passato a gevent e tutto funziona perfettamente, grazie!
gronostaj

7

Invece di chiamare http://localhost:port/endpointchiama http://127.0.0.1:port/endpoint. Ciò ha rimosso il ritardo iniziale di 500 ms per me.


per me ha rimosso qualcosa come 3 secondi (ho spostato da 0.0.0.0 a 127.0.0.1). Qualcuno può spiegare perché e come funziona?
Rotkiv

Perché in nome di Dio funziona? È passato da 2,06 secondi a 0,002 secondi. Il browser è in grado di utilizzare localhost senza problemi, ma requests.get su localhost impiega 2 secondi per risolversi.
Xevion

7

Il mio problema è stato risolto con "threaded = True", ma voglio fornire alcune informazioni di base per distinguere il mio problema da altri per i quali questo potrebbe non farlo.

  1. Il mio problema si è verificato solo durante l'esecuzione di Flask con python3. Passando a python2, non ho più avuto questo problema.
  2. Il mio problema si è manifestato solo durante l'accesso all'API con Chrome, a quel punto Chrome ha visualizzato la schermata prevista, ma tutto il resto si è bloccato (curl, ffx, ecc.) Fino a quando non ho ricaricato o chiuso la scheda Chrome, a quel punto tutto il resto che era in attesa intorno ha restituito un risultato.

La mia ipotesi migliore è che Chrome stesse cercando di mantenere la sessione aperta e Flask stesse bloccando le richieste successive. Non appena la connessione da Chrome è stata interrotta o ripristinata, tutto il resto è stato elaborato.

Nel mio caso, il threading lo ha risolto. Naturalmente, sto ora esaminando alcuni dei collegamenti forniti da altri per assicurarmi che non causerà altri problemi.


4

threaded=Truefunziona per me, ma finalmente ho capito che il problema è dovuto a foxyproxy su Firefox. Poiché quando l'app flask è in esecuzione su localhost, si verifica una risposta lenta se

  • foxyproxy è abilitato su firefox

la risposta lenta non avverrà se

  • foxyproxy è disabilitato su firefox

  • accedere al sito Web utilizzando altri browser

L'unica soluzione che ho trovato è disabilitare foxyproxy, ho provato ad aggiungere localhost alla lista nera del proxy e modificare le impostazioni ma nessuno di loro ha funzionato.


2

Ho usato la risposta di Miheko per risolvere il mio problema.

::1 localhostera già stato commentato nel mio file hosts e l'impostazione Threaded=truenon funzionava per me. Ogni richiesta REST richiedeva 1 secondo per essere elaborata invece di essere istantanea.

Sto usando python 3.6 e ho ottenuto che flask sia veloce e reattivo alle richieste REST facendo in modo che flask usi gevent come WSGI.

Per utilizzare gevent, installalo con pip install gevent

Successivamente, ho utilizzato https://gist.github.com/viksit/b6733fe1afdf5bb84a40#file-async_flask-py-L41 per impostare flask in modo che utilizzi gevent.

Nel caso in cui il collegamento si interrompa, ecco le parti importanti dello script:

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()

threaded = True non funziona per (utilizzando python 3.6.7 e postman), ricevo VersionConflict: (greenlet 0.4.13 (c: \ anaconda3 \ lib \ site-packages), Requirement.parse ('greenlet> = 0.4. 14; platform_python_implementation == "CPython" ')), posso sapere come risolvere questo problema, grazie
hanzgs

0

Ho ricevuto questo errore durante l'esecuzione su host diversi da localhostquelli, quindi per alcuni problemi sottostanti diversi potrebbero presentare gli stessi sintomi.

Ho passato la maggior parte delle cose che ho usato a Tornado, e aneddoticamente ha aiutato un po '. Ho avuto alcuni caricamenti di pagina lenti, ma le cose sembrano generalmente più reattive. Inoltre, molto aneddotico, ma mi sembra di notare che Flask da solo rallenterà nel tempo, ma Flask + Tornado meno. Immagino di usare Apache e mod_wsgirenderebbe le cose ancora migliori, ma Tornado è davvero semplice da configurare (vedi http://flask.pocoo.org/docs/deploying/others/ ).

(Inoltre, una domanda correlata: l' app Flask occasionalmente si blocca )


0

Avevo una soluzione diversa qui. Ho appena cancellato tutto .pycdalla directory del server e l'ho riavviato. A proposito, localhost era già commentato nel mio file hosts (Windows 8).

Il server si è bloccato tutto il tempo e ora funziona di nuovo bene.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.