Есть ли способ ограничить количество одновременных запросов с одного IP с Gunicorn? - PullRequest
0 голосов
/ 03 февраля 2020

В основном я использую веб-сервер Flask, который обрабатывает кучу данных и отправляет их обратно пользователю. Мы не ожидаем много пользователей ~ 60, но я заметил, что может быть проблема с параллелизмом. Прямо сейчас, если я открою вкладку и отправлю запрос на сжатие некоторых данных, это займет около 30 секунд, для нашего приложения это нормально.

Если я открою другую вкладку и отправлю один и тот же запрос в одно и то же время, Unicorn сделает это одновременно, это здорово, если у нас есть два отдельных пользователя, делающих два отдельных запроса. Но что произойдет, если один пользователь откроет 4 или 8 вкладок и отправит один и тот же запрос? Это резервное копирование сервера для всех остальных, Есть ли способ, которым я могу сказать Gunicorn принимать только 1 запрос за один раз с того же IP?

Ответы [ 2 ]

1 голос
/ 04 февраля 2020

Лучшим решением для ответа @jon было бы ограничение доступа вашего веб-сервера вместо сервера приложений. Хорошим способом всегда было бы разделение обязанностей, выполняемых различными уровнями вашего приложения. В идеале сервер приложений flask не должен иметь никакой конфигурации для ограничения или чего-либо общего с тем, откуда поступают запросы. Ответственность веб-сервера, в данном случае nginx, заключается в том, чтобы направить запрос на основе определенных параметров нужному клиенту. Ограничение должно быть сделано на этом уровне.

Теперь, приближаясь к ограничению, вы можете сделать это, используя директиву limit_req_zone в конфигурации блока http nginx

http {
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

...

server {

    ...

    location / {
        limit_req zone=one burst=5;
        proxy_pass ...
    }
* 1006. * где binary_remote_addr - это IP-адрес клиента, и в среднем допускается не более 1 запроса в секунду, при этом пакеты не превышают 5 запросов.

Pro-tip: С последующие запросы с того же IP-адреса будут храниться в очереди, есть большая вероятность истечения времени ожидания nginx. Следовательно, было бы желательно иметь лучший proxy_read_timeout и, если отчеты занимают больше времени, то также корректировать время ожидания gunicorn

Документация limit_req_zone

запись в блоге nginx по ограничению скорости можно найти здесь

0 голосов
/ 03 февраля 2020

Это, вероятно, НЕ лучше всего обрабатывать на уровне flask. Но если вам нужно было сделать это там, то оказывается, что кто-то другой уже разработал плагин flask для этого:

https://flask-limiter.readthedocs.io/en/stable/

Если запрос занимает не менее 30 секунд, затем установите лимит по адресу для одного запроса каждые 30 секунд. Это решит вопрос о том, как нетерпеливые пользователи одержимо щелкают, вместо того, чтобы ждать очень длительного процесса до конца sh.

Это не совсем то, что вы запрашивали, поскольку это означает, что более длинные / короткие запросы могут перекрываться и разрешать несколько запросов одновременно, что не полностью исключает поведение, описанное вами для нескольких вкладок, и т. Д. c. Тем не менее, если вы можете сказать своим пользователям, что нужно подождать 30 секунд, это похоже на то, что вы находитесь на месте водителя для установки ожиданий UX. Вероятно, хорошее сообщение ожидания / прогресса также поможет, если вы сможете построить асинхронное взаимодействие с сервером.

...