Permintaan Lambat di Server Flask Lokal

87

Baru mulai bermain-main dengan Flask di server lokal dan saya perhatikan waktu request / response jauh lebih lambat dari yang saya rasa seharusnya.

Hanya server sederhana seperti berikut ini membutuhkan waktu hampir 5 detik untuk merespons.

from flask import Flask

app = Flask(__name__)

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

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

Ada ide? Atau apakah ini hanya bagaimana server lokal?

Meroon
sumber
Ini bukan server lokal tetapi mungkin ada hubungannya dengan aplikasi lain yang berjalan di latar belakang OS apa yang Anda jalankan ini?
gabeio
Saya menjalankan OS X 10.7 pada i7 iMac
Meroon
1
Seharusnya tidak memakan waktu lama untuk tanggapan Anda tetapi saya sebenarnya telah mengotak-atik termos sebelum tidak berhasil, saya akan menyarankan Bottlepy . Meskipun masih memeriksa proses latar belakang Anda, Anda mungkin memiliki versi yang lebih lama dari server Anda yang berjalan di latar belakang mengambil alih python Anda dan menyebabkan respons Anda lambat. Mungkin juga browser Anda, apakah ini terjadi di chrome & safari?
gabeio
2
@ Jawaban Meroon benar untuk saya. Daripada mengubah pengaturan host, namun: Mungkinkah saya merekomendasikan hanya menggunakan 127.0.0.1 daripada localhost? Itu memecahkan masalah tanpa mengubah konfigurasi sistem.
David Bernat

Jawaban:

94

Ok saya menemukan jawabannya. Tampaknya ada masalah dengan Werkzeug dan os yang mendukung ipv6.

Dari situs Werkzeug http://werkzeug.pocoo.org/docs/serving/ :

Pada sistem operasi yang mendukung ipv6 dan telah dikonfigurasi seperti sistem Linux modern, OS X 10.4 atau lebih tinggi serta Windows Vista, beberapa browser dapat menjadi sangat lambat jika mengakses server lokal Anda. Alasan untuk ini adalah bahwa terkadang "localhost" dikonfigurasi agar tersedia pada socktes ipv4 dan ipv6 dan beberapa browser akan mencoba mengakses ipv6 terlebih dahulu dan kemudian ivp4.

Jadi perbaikannya adalah menonaktifkan ipv6 dari localhost dengan mengomentari baris berikut dari file host saya:

::1             localhost 

Setelah saya melakukan ini, masalah latensi akan hilang.

Saya benar-benar menggali Flask dan saya senang tidak ada masalah dengan kerangka kerjanya. Saya tahu itu tidak mungkin.

Meroon
sumber
Terima kasih banyak! tiba-tiba pengujian dev cepat dan responsif! satu-satunya pertanyaan saya: karena file host Mac menunjukkan bahwa menghapus localhost dapat memengaruhi operasi Mac saya, saya bertanya-tanya apakah itu merujuk ke baris ini (atau yang hanya menempatkan localhost ke 127.0.0.1
David
di sistem windows 10 saya di file host kedua entri (ip4 dan ip6) dikomentari; mereka diselesaikan oleh sistem DNS. Saya mendapat peningkatan kecepatan yang sangat besar ketika saya menjalankan server di "127.0.0.1" daripada "localhost" (dari 2,0 menjadi 0,003 detik untuk panggilan sederhana)
Lars
Terima kasih atas jawaban ini! Meskipun situasi saya sedikit berbeda (berhadapan langsung dengan aiosmtpd), jawaban Anda memberi saya petunjuk: Ketika saya menonaktifkan IPv6 di laptop Windows 10 saya mempercepat hal-hal seperti 10x atau 100x !!
pepoluan
91

Tambahkan "threaded = True" sebagai argumen ke app.run (), seperti yang disarankan di sini: http://arusahni.net/blog/2013/10/flask-multithreading.html

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

Solusi penonaktifan ipv6 tidak berhasil untuk saya, tetapi ini berhasil.

Sajid Siddiqi
sumber
5
Meneruskan penggunaan --threadedsaya juga berhasil. manage.pyFlask-Script
Snorfalorpagus
7
Bagi mereka yang membuatnya "diperbaiki" dengan mengaktifkan utas, berhati-hatilah! Dalam hal ini penundaan disebabkan oleh permintaan sebelumnya tidak ditutup dengan benar, jadi sekarang sebenarnya hanya menumpuk banyak utas .
kbtz
1
Terima kasih Pak telah membuat localhost saya bekerja sangat cepat.
benjaminz
@snolflake: Adakah cara untuk mengetahui apakah permintaan tidak ditutup dengan benar?
Kylotan
1
Dari baris perintah yang saya gunakan flask run --with-threadsyang memecahkan masalah saya.
arno_v
13

Solusi dari @ sajid-siddiqi secara teknis benar, tetapi perlu diingat bahwa server WSGI built-in di Werkzeug (yang dikemas ke dalam Flask dan untuk apa app.run()) hanya single-threaded.

Instal server WSGI agar dapat menangani perilaku multi-threaded. Saya melakukan banyak penelitian tentang berbagai kinerja server WSGI . Kebutuhan Anda mungkin berbeda, tetapi jika yang Anda gunakan hanyalah Flask , maka saya akan merekomendasikan salah satu server web berikut.

Pembaruan (2020-07-25): Sepertinya gevent mulai mendukung python3 5 tahun yang lalu, tak lama setelah saya berkomentar bahwa itu tidak, jadi Anda dapat menggunakan gevent sekarang.

gevent

Anda dapat menginstal gevent melalui pip dengan perintah pip install geventatau pip3 dengan perintah pip3 install gevent. Petunjuk tentang cara mengubah kode Anda ada di sini: https://flask.palletsprojects.com/en/1.1.x/deploying/wsgi-standalone/#gevent

meinheld

gevent lebih baik, tetapi dari semua tolok ukur yang saya lihat yang melibatkan pengujian dunia nyata, meinheld tampaknya menjadi server WSGI yang paling lugas dan sederhana . (Anda juga dapat melihat uWSGI jika Anda tidak keberatan dengan konfigurasi lainnya.)

Anda juga dapat menginstal meinheld melalui pip3 dengan perintah pip3 install meinheld. Dari sana, lihat contoh yang disediakan di sumber meinheld untuk mengintegrasikan Flask : https://github.com/mopemope/meinheld/blob/master/example/flask_sample.py

* CATATAN: Dari penggunaan PyCharm saya , garis from meinheld import serverdisorot sebagai kesalahan, tetapi server akan berjalan, sehingga Anda dapat mengabaikan kesalahan tersebut.

mikeho
sumber
Saya memiliki masalah performa yang besar dengan Flask, bahkan permintaan yang paling sederhana membutuhkan waktu sekitar 0,5 detik untuk diselesaikan. Baru saja beralih ke gevent dan semuanya bekerja dengan sempurna, terima kasih!
gronostaj
7

Bukan memanggil http://localhost:port/endpointpanggilan http://127.0.0.1:port/endpoint. Ini menghapus penundaan awal 500ms untuk saya.

LangeTreeDorpie
sumber
bagi saya itu menghapus sesuatu seperti 3seconds (saya pindah dari 0.0.0.0 ke 127.0.0.1). Adakah yang bisa menjelaskan mengapa dan bagaimana cara kerjanya?
Rotkiv
Mengapa dalam nama dewa ini berhasil? Beralih dari 2,06 detik menjadi 0,002 detik. Browser dapat menggunakan localhost tanpa masalah, tetapi requests.get di localhost membutuhkan waktu 2 detik untuk menyelesaikannya.
Xevion
7

Masalah saya diselesaikan dengan "threaded = True", tetapi saya ingin memberikan beberapa latar belakang untuk membedakan masalah saya dari masalah lain yang mungkin tidak dapat dilakukan ini.

  1. Masalah saya hanya muncul saat menjalankan Flask dengan python3. Beralih ke python2, saya tidak lagi mengalami masalah ini.
  2. Masalah saya hanya terwujud ketika mengakses api dengan Chrome, pada titik mana, Chrome menampilkan layar yang diharapkan, tetapi yang lainnya digantung (curl, ffx, dll) sampai saya memuat ulang atau menutup tab Chrome, pada titik mana semua yang lain menunggu sekitar mengembalikan hasil.

Tebakan terbaik saya adalah bahwa Chrome mencoba untuk membuat sesi tetap terbuka dan Flask memblokir permintaan berikutnya. Segera setelah koneksi dari Chrome dihentikan atau disetel ulang, yang lainnya diproses.

Dalam kasus saya, threading memperbaikinya. Tentu saja, saya sekarang akan menelusuri beberapa tautan yang telah disediakan orang lain untuk memastikan bahwa itu tidak akan menyebabkan masalah lain.

ChePazzo
sumber
4

threaded=Trueberfungsi untuk saya, tetapi akhirnya saya menemukan bahwa masalahnya adalah karena foxyproxy di firefox. Sejak saat aplikasi flask dijalankan di localhost, respon lambat terjadi jika

  • foxyproxy diaktifkan di firefox

respon lambat tidak akan terjadi jika

  • foxyproxy dinonaktifkan di firefox

  • mengakses situs web menggunakan browser lain

Satu-satunya solusi yang saya temukan adalah menonaktifkan foxyproxy, mencoba menambahkan localhost ke daftar hitam proxy dan mengubah pengaturan tetapi tidak ada yang berfungsi.

Edward
sumber
2

Saya menggunakan tanggapan Miheko untuk menyelesaikan masalah saya.

::1 localhostsudah dikomentari di file host saya, dan pengaturan Threaded=truetidak berfungsi untuk saya. Setiap permintaan REST membutuhkan waktu 1 detik untuk diproses, bukan instan.

Saya menggunakan python 3.6, dan saya mendapatkan flask untuk menjadi cepat dan responsif terhadap permintaan REST dengan membuat flask menggunakan gevent sebagai WSGI-nya.

Untuk menggunakan gevent, instal dengan pip install gevent

Setelah itu, saya menggunakan https://gist.github.com/viksit/b6733fe1afdf5bb84a40#file-async_flask-py-L41 untuk mengatur flask agar menggunakan gevent.

Jika tautan turun, inilah bagian penting dari skrip:

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()
Beberapa pria
sumber
threaded = True tidak berfungsi untuk (menggunakan python 3.6.7 dan tukang pos), saya mendapatkan VersionConflict: (greenlet 0.4.13 (c: \ anaconda3 \ lib \ site-packages), Requirement.parse ('greenlet> = 0.4. 14; platform_python_implementation == "CPython" ')), bolehkah saya tahu cara menyelesaikannya, Terima kasih
hanzgs
0

Saya mendapat kesalahan ini saat menjalankan host selain localhostjuga, jadi untuk beberapa, masalah mendasar yang berbeda mungkin menunjukkan gejala yang sama.

Saya mengganti sebagian besar hal yang telah saya gunakan ke Tornado, dan secara anekdot itu sangat membantu. Saya mengalami beberapa pemuatan halaman yang lambat, tetapi semuanya tampak lebih responsif. Juga, sangat anekdot, tapi saya melihat bahwa Flask sendiri akan melambat seiring waktu, tapi Flask + Tornado kurang begitu. Saya membayangkan menggunakan Apache dan mod_wsgiakan membuat segalanya menjadi lebih baik, tetapi Tornado sangat mudah disiapkan (lihat http://flask.pocoo.org/docs/deploying/others/ ).

(Juga, pertanyaan terkait: aplikasi Flask terkadang hang )

gatoatigrado.dll
sumber
0

Saya punya solusi berbeda di sini. Saya baru saja menghapus semua.pyc dari direktori server dan memulainya lagi. Ngomong-ngomong, localhost sudah diberi komentar di file host saya (Windows 8).

Server membeku sepanjang waktu dan sekarang berfungsi dengan baik lagi.

erickrf
sumber