Обслуживание Python (Flask) REST API через HTTP2

У меня есть служба REST Python, и я хочу обслуживать ее с помощью HTTP2. Моя текущая настройка сервера nginx -> Gunicorn. Другими словами, nginx (порт 443 и 80, который перенаправляется на порт 443) работает как обратный прокси-сервер и отправляет запросы в Gunicorn (порт 8000, без SSL). nginx работает в режиме HTTP2, и я могу проверить, что с помощью chrome и проверки столбца "protocol" после отправки простого GET на сервер. Однако Gunicorn сообщает, что запросы, которые он получает, являются HTTP1.0. Кроме того, я не могу найти его в этом списке: https://github.com/http2/http2-spec/wiki/Implementations Итак, мои вопросы:

  • Можно ли использовать приложение Python (Flask) с HTTP2? Если да, какие серверы поддерживают его?
  • В моем случае (один обратный прокси-сервер и один обслуживающий фактический API), какой сервер должен поддерживать HTTP2?

Причина, по которой я хочу использовать HTTP2, заключается в том, что в некоторых случаях мне нужно выполнять тысячи запросов вместе, и мне было интересно узнать, может ли функция мультиплексированных запросов HTTP2 ускорить процесс. С запросами HTTP1.0 и Python в качестве клиента каждый запрос занимает ~ 80 мс, что неприемлемо. Другим решением было бы просто загрузить/загрузить ресурсы REST и отправить несколько запросов с одним запросом. Да, эта идея звучит просто отлично, но мне действительно интересно узнать, может ли HTTP2 ускорить процесс.

Наконец, я должен упомянуть, что для клиентской стороны я использую запросы Python с адаптером Hyper http2.

Ответ 1

Можно ли использовать приложение Python (Flask) с HTTP/2?

Да, по информации, которую вы предоставляете, вы делаете это просто отлично.

В моем случае (один обратный прокси-сервер и один обслуживающий фактический API), какой сервер должен поддерживать HTTP2?

Теперь я буду шагать по тонкому льду и давать мнения.

Способ, которым был распространен HTTP/2, заключается в использовании пограничного сервера, который говорит HTTP/2 (например, ShimmerCat или NginX). Этот сервер завершает TLS и HTTP/2, а оттуда использует HTTP/1, HTTP/1.1 или FastCGI для общения с внутренним приложением.

Можно ли, по крайней мере теоретически, использовать пограничный сервер HTTP/2 для веб-приложения? Да, но HTTP/2 сложный и для внутренних приложений он не очень хорошо окупается.

Это потому, что большинство фреймворков веб-приложений созданы для обработки запросов на контент, и это достаточно хорошо работает с HTTP/1 или FastCGI. Хотя есть исключения, веб-приложения мало используют для тонкостей HTTP/2: мультиплексирования, определения приоритетов, множества несложных мер предосторожности и т.д.

В результате разделение проблем, на мой взгляд, хорошо.


Время ответа 80 мс может иметь мало общего с протоколом HTTP, который вы используете, но если эти 80 мс в основном потрачены на ожидание ввода/вывода, то, конечно, параллельная работа идет хорошо.

Gunicorn будет использовать поток или процесс для обработки каждого запроса (если только вы не переместили лишнюю милю для настройки блендера greenlets), поэтому подумайте о том, может ли Gunicorn создать тысячи задач в вашем случае.

Если содержимое ваших запросов позволяет это, возможно, вы можете создавать временные файлы и обслуживать их с помощью пограничного сервера HTTP/2.

Ответ 2

Теперь можно использовать HTTP/2 непосредственно из приложения Python, например, используя Twisted. Вы спросили конкретно о приложении Flask, хотя в этом случае я (с предубеждением) рекомендую Quart, который является API-интерфейсом Flask, повторно реализованным на top of asyncio (с поддержкой HTTP/2).

Ваша актуальная проблема,

С запросами HTTP1.0 и Python в качестве клиента каждый запрос занимает ~ 80 мс

предлагает мне, что проблема, с которой вы можете столкнуться, заключается в том, что каждый запрос открывает новое соединение. Это можно было бы облегчить с помощью пула соединений не требуя HTTP/2.