Yerel Flask Sunucusundaki Yavaş İstekler


87

Yerel bir sunucuda Flask ile oynamaya başladım ve istek / yanıt sürelerinin olması gerekenden çok daha yavaş olduğunu fark ediyorum.

Sadece aşağıdaki gibi basit bir sunucunun yanıt vermesi 5 saniyeye yakın sürer.

from flask import Flask

app = Flask(__name__)

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

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

Herhangi bir fikir? Yoksa yerel sunucu bu şekilde mi?


Yerel sunucu değil, ancak arka planda çalışan diğer uygulamalarla ilgisi olabilir, bunu hangi işletim sisteminde çalıştırıyorsunuz?
gabeio


1
Yanıtlarınız bu kadar uzun sürmemeli , ancak daha önce şişeyle uğraştım ve hiçbir başarıya ulaşamadığım için Bottlepy'ye tavsiye ederim . Yine de arka plan işlemlerinizi kontrol etseniz de, sunucunuzun arka planda çalışan eski bir sürümü python'unuzu devralabilir ve yavaş yanıtlarınıza neden olabilir. Ayrıca tarayıcınız Chrome & Safari'de de olabilir mi?
gabeio

2
@ Meroon'un cevabı benim için doğruydu. Ancak, ana bilgisayar ayarlarını değiştirmek yerine: localhost yerine sadece 127.0.0.1 kullanmanızı tavsiye edebilir miyim? Bu, sistem yapılandırmasını değiştirmeden sorunu çözdü.
David Bernat

Yanıtlar:


94

Tamam anladım. IPv6'yı destekleyen Werkzeug ve OS'ler ile ilgili bir sorun gibi görünüyor.

Werkzeug sitesinden http://werkzeug.pocoo.org/docs/serving/ :

İpv6'yı destekleyen ve modern Linux sistemleri, OS X 10.4 veya üstü ve Windows Vista gibi yapılandırılmış işletim sistemlerinde, bazı tarayıcılar yerel sunucunuza erişirken çok yavaş olabilir. Bunun nedeni bazen “localhost” un hem ipv4 hem de ipv6 sockte'larında kullanılabilecek şekilde yapılandırılması ve bazı tarayıcıların önce ipv6'ya sonra ivp4'e erişmeye çalışacak olmasıdır.

Bu nedenle, ana bilgisayar dosyamdan aşağıdaki satırı yorumlayarak ipv6'yı localhost'tan devre dışı bırakmaktır:

::1             localhost 

Bunu yaptığımda gecikme sorunları ortadan kalkıyor.

Flask'ı gerçekten kazıyorum ve çerçeveyle ilgili bir sorun olmadığına sevindim. Olamayacağını biliyordum.



çok teşekkürler! aniden geliştirme testi hızlı ve hızlıdır! Benim tek soru: Mac hosts dosyası localhost'u kaldırarak bu hat (veya basitçe 127.0.0.1 için localhost bulur o birine atıfta olup olmadığını merak ediyorum, benim Mac'in operasyonlarını büyük ölçüde etkileyebileceğine işaret olarak
David B.

Windows 10 sistemimde ana bilgisayar dosyasındaki her iki giriş (ip4 ve ip6) yorumlanır; DNS sistemi tarafından çözülürler. Sunucuyu "localhost" yerine "127.0.0.1" üzerinde çalıştırdığımda büyük bir hız artışı elde ettim (basit çağrılar için 2,0'dan 0,003 saniyeye)
Lars

Bu cevap için teşekkürler! Durumum biraz farklı olsa da (aiosmtpd'ye karşı burnu çalıştırmak), cevabınız bana bir ipucu verdi: Windows 10 dizüstü bilgisayarımda IPv6'yı devre dışı bıraktığımda 10x veya 100x gibi şeyleri hızlandırıyor !!
pepoluan

91

Burada önerildiği gibi app.run () öğesine bağımsız değişken olarak "threaded = True" ekleyin: http://arusahni.net/blog/2013/10/flask-multithreading.html

Örneğin: app.run(host="0.0.0.0", port=8080, threaded=True)

İpv6 devre dışı bırakma çözümü benim için işe yaramadı, ancak bu işe yaradı.


5
Geçme --threadedbenim için manage.pykullanarak Flask-Scriptçok çalıştı.
Snorfalorpagus

7
Konuları etkinleştirerek "düzeltilmiş" olanlar için uyarılırsınız! Bu durumda gecikme, önceki talebin düzgün bir şekilde kapatılmamasından kaynaklanıyordu, bu yüzden şimdi aslında sadece çok sayıda iş parçacığı yığılıyor .
kbtz

1
Yerel ev sahibimi son derece hızlı çalıştırdığınız için teşekkür ederim efendim.
benjaminz

@snolflake: İsteklerin doğru şekilde kapatılıp kapatılmadığını bilmenin bir yolu var mı?
Kylotan

1
flask run --with-threadsSorunumu çözen komut satırından .
arno_v

13

@ Sajid-Siddiqi'deki gelen çözüm yerleşik olduğu teknik olarak doğru, ama akılda tutmak WSGI sunucu Werkzeug (içine paketlenmiş Flask ve ne için kullandığı app.run()tek tek iş parçacıklı) 'dir.

Çok iş parçacıklı davranışı işleyebilmek için bir WSGI sunucusu kurun . Çeşitli WSGI sunucu performansları hakkında bir dizi araştırma yaptım . İhtiyaçlarınız değişebilir, ancak tek kullandığınız Flask ise, aşağıdaki web sunucularından birini tavsiye ederim.

Güncelleme (2020-07-25): Görünüşe göre gevent python3'ü 5 yıl önce desteklemeye başladı , ben desteklemediğini yorumladıktan kısa bir süre sonra gevent'i şimdi kullanabilirsiniz .

gevent

Sen yükleyebilir gevent yoluyla pip komutuyla pip install geventya PIP3 komutuyla pip3 install gevent. Kodunuzu buna göre nasıl değiştireceğinizle ilgili talimatlar burada: https://flask.palletsprojects.com/en/1.1.x/deploying/wsgi-standalone/#gevent

meinheld

gevent daha iyidir, ancak gerçek dünya testlerini içeren tüm kıyaslamalardan bakıldığında, meinheld en basit, en basit WSGI sunucusu gibi görünüyor . (Daha fazla yapılandırmaya aldırmazsanız uWSGI'ye de göz atabilirsiniz .)

Ayrıca yükleyebilirsiniz meinheld aracılığıyla PIP3 komutuyla pip3 install meinheld. Oradan, sağlanan numunenin bakmak meinheld kaynağına entegre etmek Flask : https://github.com/mopemope/meinheld/blob/master/example/flask_sample.py

* NOT: PyCharm kullanımımdan dolayı , satır from meinheld import serverbir hata olarak vurgulanır, ancak sunucu çalışacaktır, böylece hatayı göz ardı edebilirsiniz.


Flask ile ilgili büyük performans sorunlarım vardı, en basit isteklerin bile tamamlanması yaklaşık 0,5 saniye sürüyordu. Sadece gevent'e geçtim ve her şey kusursuz çalışıyor, teşekkürler!
gronostaj

7

Çağrı http://localhost:port/endpointaramak yerine http://127.0.0.1:port/endpoint. Bu benim için ilk 500 ms gecikmeyi kaldırdı.


benim için 3 saniye gibi bir şeyi kaldırdı (0.0.0.0 biçimini 127.0.0.1'e taşıdım). Birisi neden ve nasıl çalıştığını açıklayabilir mi?
Rotkiv

Tanrılar adına bu neden işe yarar? 2,06 saniyeden 0,002 saniyeye çıktı. Tarayıcı, localhost'u sorunsuz bir şekilde kullanabilir, ancak request.get on localhost'un çözülmesi 2 saniye sürer.
Xevion

7

Sorunum "threaded = True" ile çözüldü, ancak problemimi diğerlerinden ayırt etmek için biraz arka plan vermek istiyorum, bunun için bunu yapmayabilirim.

  1. Sorunum yalnızca Flask'ı python3 ile çalıştırırken ortaya çıktı. Python2'ye geçerken, artık bu sorunu yaşamadım.
  2. Sorunum yalnızca API'ye Chrome ile erişirken ortaya çıktı , bu noktada Chrome beklenen ekranı görüntüledi, ancak Chrome sekmesini yeniden yükleyene veya kapatana kadar her şey (curl, ffx vb.) Asılı kaldı, bu noktada bekleyen her şey around bir sonuç döndürdü.

En iyi tahminim, Chrome'un oturumu açık tutmaya çalıştığı ve Flask'ın sonraki istekleri engellediği. Chrome'dan bağlantı durdurulduğunda veya sıfırlandığında, geri kalan her şey işlendi.

Benim durumumda, diş açma sorunu çözdü. Tabii ki, şimdi başka sorunlara neden olmayacağından emin olmak için diğerlerinin sağladığı bağlantılardan bazılarını gözden geçiriyorum.


4

threaded=Truebenim için çalışıyor, ama sonunda sorunun firefox'taki foxyproxy'den kaynaklandığını anladım. Cep şişesi uygulaması localhost'ta çalıştığından, yanıt yavaşsa

  • foxyproxy, firefox'ta etkinleştirildi

yavaş yanıt olmazsa

  • foxyproxy, firefox'ta devre dışı bırakıldı

  • web sitesine diğer tarayıcıları kullanarak erişin

Bulduğum tek çözüm foxyproxy'yi devre dışı bırakmak, proxy kara listesine localhost eklemeyi denedi ve ayarları değiştirdi ancak hiçbiri işe yaramadı.


2

Sorunumu çözmek için Miheko'nun yanıtını kullandım.

::1 localhostana bilgisayar dosyamda zaten yorumlanmıştı ve ayar benim Threaded=trueiçin çalışmadı. Her REST talebinin işlenmesi anlık olmak yerine 1 saniye sürüyordu.

Python 3.6 kullanıyorum ve flask'ı WSGI olarak gevent kullanarak REST isteklerine hızlı ve duyarlı olmak için flask aldım.

Gevent'i kullanmak için, pip install gevent

Daha sonra, şişeyi gevent kullanmak için ayarlamak için https://gist.github.com/viksit/b6733fe1afdf5bb84a40#file-async_flask-py-L41'i kullandım.

Bağlantının kopması durumunda, betiğin önemli kısımları:

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 için çalışmıyor (python 3.6.7 ve postacı kullanıyor), VersionConflict: (greenlet 0.4.13 (c: \ anaconda3 \ lib \ site-packages), Requirement.parse ('greenlet> = 0.4. 14; platform_python_implementation == "CPython" ')), bunu nasıl çözeceğimi öğrenebilir miyim, Teşekkürler
hanzgs

0

Bu hatayı başka ana bilgisayarlarda da çalışırken aldım localhost, bu nedenle bazıları için farklı temel sorunlar aynı belirtileri gösterebilir.

Kullandığım şeylerin çoğunu Tornado'ya değiştirdim ve anekdot olarak bir miktar yardımcı oldu. Birkaç yavaş sayfa yüklemem oldu, ancak işler genellikle daha duyarlı görünüyor. Ayrıca, çok anekdot, ancak Flask'ın tek başına zamanla yavaşlayacağını, ancak Flask + Tornado'nun daha az yavaşlayacağını fark ettim. Apache kullanmayı hayal mod_wsgiediyorum ve işleri daha da iyi hale getirebilirim, ancak Tornado'nun kurulumu gerçekten çok basit (bkz. Http://flask.pocoo.org/docs/deploying/others/ ).

(Ayrıca ilgili bir soru: Flask uygulaması ara sıra asılı )


0

Burada farklı bir çözümüm vardı. Sadece .pycsunucunun dizininden hepsini sildim ve yeniden başlattım. Bu arada, localhost zaten ana bilgisayar dosyamda (Windows 8) yorumlanmıştı.

Sunucu sürekli donuyordu ve şimdi tekrar iyi çalışıyor.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.