Повільні запити на сервері Local Flask


87

Тільки починаючи гратись з Flask на локальному сервері, і я помічаю, що час запитів / відповідей набагато повільніший, ніж я вважаю, що він повинен бути.

Простому серверу, як показано нижче, потрібно близько 5 секунд, щоб відповісти.

from flask import Flask

app = Flask(__name__)

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

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

Будь-які ідеї? Або це просто локальний сервер?


Це не локальний сервер, але, можливо, це пов’язано з іншими програмами, що працюють у фоновому режимі, на якій ОС ви працюєте?
gabeio

Я працюю в OS X 10.7 на i7 iMac
Meroon

1
Це не повинно зайняти так багато часу для ваших відповідей, але я насправді переплутався з колбою до безуспішності, я б порадив Bottlepy . Хоча все ще перевіряйте фонові процеси, можливо, у вас старіша версія вашого сервера працює у фоновому режимі, переймаючи ваш python і викликаючи ваші повільні відповіді. Також це може бути ваш браузер, чи трапляється це в chrome & safari?
gabeio

2
Відповідь @ Meroon для мене була правильною. Замість того, щоб змінювати налаштування хоста, однак: Чи не рекомендую я просто використовувати 127.0.0.1 замість localhost? Це вирішило проблему без зміни конфігурації системи.
Девід Бернат,

Відповіді:


93

Гаразд, я це зрозумів. Здається, це проблема з Werkzeug та ОС, які підтримують ipv6.

З веб-сайту Werkzeug http://werkzeug.pocoo.org/docs/serving/ :

В операційних системах, які підтримують ipv6 та налаштовують його, таких як сучасні системи Linux, OS X 10.4 або новішої версії, а також Windows Vista, деякі браузери можуть бути болісно повільними при доступі до локального сервера. Причиною цього є те, що інколи “localhost” налаштовується на доступ як на socktes ipv4, так і ipv6, і деякі браузери намагатимуться спочатку отримати доступ до ipv6, а потім ivp4.

Отже, виправлення полягає у відключенні ipv6 з localhost, коментуючи наступний рядок з мого файлу hosts:

::1             localhost 

Як тільки я це роблю, проблеми із затримкою зникають.

Я справді копаю Flask і радий, що це не проблема з фреймворком. Я знав, що цього не може бути.



дуже дякую! раптом тестування розробників є швидким та чуйним! моє єдине запитання: оскільки файл хостів Mac вказує на те, що видалення localhost може вплинути на операції мого Mac, цікаво, чи посилається він на цей рядок (чи той, який просто визначає localhost до 127.0.0.1
Девід Б.,

у моїй системі Windows 10 у файлі hosts коментуються обидва записи (ip4 та ip6); їх вирішує система DNS. Я отримав величезне збільшення швидкості, коли запустив сервер на "127.0.0.1" замість "localhost" (з 2,0 до 0,003 сек для простих дзвінків)
Ларс,

Дякую за цю відповідь! Хоча моя ситуація була дещо іншою (запуск nose2 проти aiosmtpd), ваша відповідь дала мені підказку: Коли я вимикаю IPv6 на своєму ноутбуці з Windows 10, пришвидшує такі речі, як 10x або 100x !!
pepoluan

87

Додайте "threaded = True" як аргумент до app.run (), як пропонується тут: http://arusahni.net/blog/2013/10/flask-multithreading.html

Наприклад: app.run(host="0.0.0.0", port=8080, threaded=True)

Рішення для відключення ipv6 у мене не працювало, але це спрацювало.


5
Перехід --threadedдо мого manage.pyвикористання Flask-Scriptтеж спрацював.
Snorfalorpagus

7
Для тих, хто отримує "виправлення", увімкнувши потоки, будьте попереджені! У цьому випадку затримка була викликана неправильним закриттям попереднього запиту, тому зараз він фактично просто складає багато потоків .
kbtz

Дякую, сер, що ви змусили мого локального хоста працювати швидко.
Бенджамінц,

@snolflake: Чи є спосіб дізнатись, чи не закриваються запити належним чином?
Кілотан,

1
З командного рядка, який я використав, flask run --with-threadsвирішив мою проблему.
arno_v

13

Рішення від @ sajid-siddiqi є технічно правильним, але майте на увазі, що вбудований сервер WSGI у Werkzeug (який упакований в Flask і для чого він використовується app.run()) є лише однопотоковим.

Встановіть сервер WSGI, щоб мати можливість обробляти багатопотокову поведінку. Я провів купу досліджень з різних WSGI характеристик серверів . Ваші потреби можуть відрізнятися, але якщо все, що ви використовуєте, - Flask , я рекомендую один із наведених веб-серверів.

Оновлення (2020-07-25): Схоже, gevent почав підтримувати python3 5 років тому, незабаром після того, як я прокоментував, що цього не зробив, тож ви можете використовувати gevent зараз.

гевент

Ви можете встановити gevent через pip за допомогою команди pip install geventабо pip3 за допомогою команди pip3 install gevent. Інструкції щодо відповідної модифікації коду ви знайдете тут: https://flask.palletsprojects.com/en/1.1.x/deploying/wsgi-standalone/#gevent

мінхельд

gevent краще, але з усіх тестів, які я розглядав і включають реальне тестування, meinheld, здається, є найпростішим, спрощеним сервером WSGI . (Ви також можете поглянути на uWSGI якщо вам не ще якась конфігурація.)

Ви також можете встановити meinheld через pip3 за допомогою команди pip3 install meinheld. Звідти, подивіться на зразок, наведений у джерелі, що містить мене, для інтеграції колби : https://github.com/mopemope/meinheld/blob/master/example/flask_sample.py

* ПРИМІТКА. Після мого використання PyCharm , рядок from meinheld import serverвиділяється як помилка, але сервер буде працювати, тому ви можете ігнорувати помилку.


У мене були серйозні проблеми з продуктивністю з Flask, навіть найпростіші запити займали близько 0,5 с. Просто перейшов на gevent і все працює бездоганно, дякую!
гроностай

7

Мою проблему було вирішено за допомогою "threaded = True", але я хочу надати деякі передумови, щоб відрізнити мою проблему від інших, для яких це може не робити.

  1. Моя проблема виникла лише під час запуску Flask з python3. Переключившись на python2, у мене більше не було цієї проблеми.
  2. Моя проблема проявилася лише при доступі до API з Chrome, і в цей момент Chrome показав очікуваний екран, але все інше зависло (curl, ffx тощо), поки я не перезавантажив або не закрив вкладку Chrome, після чого все інше, що чекало навколо повернув результат.

Я найкраще здогадуюсь, що Chrome намагався тримати сесію відкритою, а Flask блокував наступні запити. Як тільки з'єднання з Chrome було зупинено або скинуто, все інше було оброблено.

У моєму випадку різьблення це виправило. Звичайно, я зараз переглядаю деякі посилання, які надавали інші, щоб переконатися, що це не спричинить жодних інших проблем.


6

Замість http://localhost:port/endpointдзвінка http://127.0.0.1:port/endpoint. Це усунуло початкову затримку 500 мс для мене.


для мене він видалив щось приблизно 3 секунди (я перемістив форму 0.0.0.0 до 127.0.0.1). Хтось може пояснити, чому і як це працює?
Ротків

Чому це в ім'я бога це працює? Пройшов від 2,06 секунди до 0,002 секунди. Браузер може використовувати localhost без проблем, але для виправлення запитів на localhost вимагається 2 секунди.
Xevion

4

threaded=Trueпрацює для мене, але врешті-решт я зрозумів, що проблема пов’язана з фоксипроксі у firefox. Оскільки, коли програма-колба працює на localhost, повільна реакція трапляється, якщо

  • foxyproxy увімкнено у Firefox

повільна реакція не відбудеться, якщо

  • foxyproxy вимкнено у Firefox

  • отримати доступ до веб-сайту за допомогою інших браузерів

Єдине рішення, яке я знайшов, - це вимкнути foxyproxy, спробував додати localhost до чорного списку і налаштувань проксі, але жоден з них не працював.


2

Я використав відповідь Міхеко, щоб вирішити своє питання.

::1 localhost вже прокоментували мій файл хостів та налаштування Threaded=true для мене не спрацювало. Кожен запит REST займав 1 секунду для обробки, а не миттєвий.

Я використовую python 3.6, і я отримав flask для швидкого реагування на запити REST, зробивши flask використання gevent як свого WSGI.

Щоб використовувати gevent, встановіть його за допомогою pip install gevent

Згодом я використав https://gist.github.com/viksit/b6733fe1afdf5bb84a40#file-async_flask-py-L41 щоб встановити колбу для використання gevent.

Якщо посилання опускається, ось важливі частини сценарію:

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 не працює (з використанням python 3.6.7 і листоноші), я отримую VersionConflict: (greenlet 0.4.13 (c: \ anaconda3 \ lib \ site-пакети), Requirement.parse ('greenlet> = 0.4. 14; platform_python_implementation == "CPython" '))), можу я знати, як це вирішити, дякую
hanzgs

0

Я отримав цю помилку під час роботи на хостах, відмінних від localhost , а також, тому для деяких, різні основні проблеми можуть мати однакові симптоми.

Більшість речей, якими я користувався, я перевів на "Торнадо", і анекдотично це допомогло. У мене було кілька повільних завантажень сторінок, але все здається загалом більш чуйним. Крім того, дуже анекдотично, але, здається, я помічаю, що Flask з часом сповільниться, а Flask + Tornado - менше. Я думаю, що я використовую Apache і mod_wsgiзробив би це ще краще, але Tornado дійсно простий у налаштуванні (див. Http://flask.pocoo.org/docs/deploying/others/ ).

(Також відповідне запитання: додаток Flask час від часу зависає )


0

У мене тут було інше рішення. Я просто видалив усі.pyc з каталогу сервера і запустив його знову. До речі, localhost вже був прокоментований у моєму файлі hosts (Windows 8).

Сервер весь час зависав, і тепер він знову працює нормально.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.