FastAPI — это современная, быстрая (высокопроизводительная) веб-инфраструктура для создания API-интерфейсов с Python 3.7+ на основе стандартных подсказок типа Python. FastAPI очень популярен благодаря поддержке асинхронности. И поскольку асинхронность в Python — это гораздо более новая концепция, в производственных средах могут возникнуть некоторые проблемы при работе с часто используемыми API.
При вызове вызовов блокировки синхронизации в асинхронных представлениях основной поток замораживается и снижается RPS (запрос в секунду) и параллелизм. Для этого вы можете использовать неасинхронные представления только с ключевым словом def func() или, если очень важно использовать асинхронные представления, скажем, вам нужно также вызвать асинхронный вызов в вашем представлении. . В этот раз вы можете использовать run_in_threadpool FastAPI, который в свою очередь использует AnyIO .to_thread.run_sync. Что он делает, так это создает новый поток или использует один из потоков и выполняет там вызов синхронизации, а затем возвращает ответ из этого потока, и из-за этого вы не блокируете основной поток. Давайте проведем несколько тестов.
Наш код выглядит так:
@app.get("/") async def read_root(): logging.warning('Started') time.sleep(1) logging.warning('Finished') return {"Hello": "World"}
Как видите, он выполняет только 1 RPS и обрабатывает второй запрос после завершения первого. Давайте не будем тестировать пример run_in_threadpool.
from fastapi.concurrency import run_in_threadpool @app.get("/") async def read_root(): logging.warning('Started') await run_in_threadpool(time.sleep,1) logging.warning('Finished') return {"Hello": "World"}
Да, мы получили то, что хотели. Теперь все запросы обрабатываются практически одновременно с высокой степенью параллелизма.
Не забудьте подписаться, чтобы получать уведомления о новых статьях