web-dev-qa-db-fra.com

Requêtes lentes sur le serveur Flask local

Je viens juste de commencer à jouer avec Flask sur un serveur local et je remarque que les temps de requête/réponse sont bien plus lents que je ne le pense.

Un simple serveur comme celui-ci prend environ 5 secondes pour répondre.

from flask import Flask

app = Flask(__name__)

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

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

Des idées? Ou s'agit-il simplement du serveur local?

66
Meroon

Ok je l'ai compris. Cela semble être un problème avec Werkzeug et les OS qui prennent en charge ipv6.

Depuis le site Werkzeug http://werkzeug.pocoo.org/docs/serving/ :

Sur les systèmes d'exploitation prenant en charge ipv6 et configuré, tels que les systèmes Linux modernes, OS X 10.4 ou ultérieure, ainsi que Windows Vista, certains navigateurs peuvent être extrêmement lents si vous accédez à votre serveur local. La raison en est que parfois «localhost» est configuré pour être disponible sur les socktes ipv4 et ipv6 et certains navigateurs essaieront d’accéder à ipv6 d’abord, puis ivp4. 

Le correctif consiste donc à désactiver ipv6 de l'hôte local en commentant la ligne suivante de mon fichier hosts:

::1             localhost 

Une fois que je fais cela, les problèmes de latence disparaissent.

Je suis vraiment en train de creuser Flask et je suis heureux que ce ne soit pas un problème avec le framework. Je savais que ça ne pouvait pas être.

80
Meroon

Ajoutez "threaded = True" comme argument à app.run (), comme suggéré ici: http://arusahni.net/blog/2013/10/flask-multithreading.html

Par exemple: app.run(Host="0.0.0.0", port=8080, threaded=True)

La solution de désactivation d'ipv6 n'a pas fonctionné pour moi, mais cela a fonctionné. 

74
Sajid Siddiqi

La solution de @ sajid-siddiqi est techniquement correcte, mais gardez à l'esprit que le serveur WSGI intégré à Werkzeug (qui est intégré à Flask et à ses utilisations pour app.run()).

Installez un serveur WSGI pour pouvoir gérer le comportement multi-thread. J'ai effectué de nombreuses recherches sur diverses performances du serveur WSGI. Vos besoins peuvent varier, mais si tout ce que vous utilisez est Flask, je vous recommande l'un des serveurs Web suivants.

Pour Python 2.x: gevent

Vous pouvez installer gevent via pip à l’aide de la commande pip install gevent. Les instructions pour modifier votre code en conséquence se trouvent ici: http://flask.pocoo.org/docs/0.10/deploying/wsgi-standalone/#gevent

Pour Python 3.x: meinheld

gevent est préférable, mais il n'a toujours pas été mis à jour pour utiliser python3 (voir ce fil pour les mises à jour: https://github.com/gevent/gevent/issues/38 ). Parmi tous les tests que j'ai examinés et qui impliquent des tests sur le terrain, meinheld semble être le serveur le plus simple et simpliste WSGI. (Vous pouvez aussi jeter un oeil à uWSGI si cela ne vous dérange pas de plus de configuration.)

Vous pouvez également installer meinheld via pip3 avec la commande pip3 install meinheld. À partir de là, regardez l'exemple fourni dans la source meinheld à intégrer Flask: https://github.com/mopemope/meinheld/blob/master/example/flask_sample.py

* REMARQUE: D'après mon utilisation de PyCharm, la ligne from meinheld import server est mise en évidence comme une erreur, mais le serveur s'exécutera afin que vous puissiez l'ignorer.

6
mikeho

Je n'ai pas encore la réputation de commenter, je vais donc ajouter ceci en tant que "solution" . Mon problème a été résolu par "threaded = True", mais je souhaite donner un peu de contexte pour distinguer mon problème des autres pour lequel cela ne peut pas le faire.

  1. Mon problème ne se pose que lors de l'exécution de Flask avec python3. En passant à python2, je n’avais plus ce problème.
  2. Mon problème s'est manifesté seulement lors de l'accès à l'API avec Chrome, Chrome a alors affiché l'écran attendu, mais tout le reste a été bloqué (curl, ffx, etc.) jusqu'à ce que je recharge ou ferme l'onglet Chrome, puis tout le reste qui attendait a donné un résultat.

Ma meilleure hypothèse est que Chrome essayait de garder la session ouverte et que Flask bloquait les requêtes suivantes. Dès que la connexion à partir de Chrome a été arrêtée ou réinitialisée, tout le reste a été traité.

Dans mon cas, le filetage l'a corrigé. Bien sûr, je suis en train de passer en revue certains des liens que d'autres ont fournis pour s'assurer que cela ne causera pas d'autres problèmes.

5
ChePazzo

threaded=True fonctionne pour moi, mais j'ai finalement compris que le problème était dû à foxyproxy sur Firefox. Depuis que l'application de flacon est en cours d'exécution sur localhost, une réponse lente se produit si

  • foxyproxy est activé sur firefox

réponse lente ne se produira pas si

  • foxyproxy est désactivé sur firefox

  • accéder au site en utilisant d'autres navigateurs

La seule solution que j'ai trouvée est de désactiver foxyproxy. Nous avons essayé d'ajouter localhost à la liste noire du proxy et aux paramètres de Tweak, mais aucun d'entre eux n'a fonctionné.

3
edward

Cette erreur s'est produite lors de l'exécution sur des hôtes autres que localhost. Ainsi, pour certains, différents problèmes sous-jacents peuvent présenter les mêmes symptômes.

J'ai remplacé la plupart des choses que j'utilise par Tornado, et de façon anecdotique, cela m'a aidé beaucoup. J'ai eu quelques pages lentes à charger, mais les choses semblent généralement plus réactives. Aussi, très anecdotique, mais je semble avoir remarqué que Flask seul ralentira avec le temps, mais Flask + Tornado le sera moins. J'imagine qu'utiliser Apache et mod_wsgi rendrait les choses encore meilleures, mais Tornado est très simple à configurer (voir http://flask.pocoo.org/docs/deploying/others/ ).

(En outre, une question connexe: Flask app suspendue occasionnellement )

0
gatoatigrado

J'ai eu une solution différente ici. Je viens de supprimer tous les .pyc du répertoire du serveur et de le redémarrer ..__ En passant, localhost a déjà été commenté dans mon fichier hosts (Windows 8).

Le serveur était gelé tout le temps et maintenant ça marche à nouveau.

0
erickrf

J'ai utilisé la réponse de Miheko pour résoudre mon problème.

::1 localhost a déjà été commenté sur mon fichier hosts, et la définition de Threaded=true n'a pas fonctionné pour moi. Chaque demande REST prenait 1 seconde à traiter au lieu d’être instantanée.

J'utilise python 3.6, et flacon a été rapide et réactif aux demandes REST en utilisant flask, qui utilise gevent comme WSGI.

Pour utiliser gevent, installez-le avec pip install gevent

Ensuite, j'ai utilisé https://Gist.github.com/viksit/b6733fe1afdf5bb84a40#file-async_flask-py-L41 pour régler le flask sur l'utilisation de gevent.

Si le lien tombe, voici les parties importantes du 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 __== '__main__':
    main()
0
Ali Mizan