Nginx-ru mailing list archive (nginx-ru@sysoev.ru)
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Реализация multiple limit_req
On 14.12.2011 18:24, Maxim Dounin wrote:
E.g. типичная ситуация для хостинга, когда лимиты хочется на
каждый $host (чтобы один атакуемый сайт не мог съесть все
ресурсы), и на ip (чтобы с одного ip-адреса, вздремнув на ^R,
нельзя было съесть все ресурсы):
limit_req<per-host>;
limit_req<per-ip>;
Если атакуют $host, то всё хорошо.
Если ^R, то проблема: легко "выедается" лимит на $host (хотя
запросы реально не обслуживаются), и тем самым нужный хост
фактически блокируется.
В данном конкретном случае - проблема легко решается сменой
порядка применения лимитов: сначала per-ip, потом per-host.
Вопрос: есть ли в реальной жизни задачи, где проблема так *не*
решается?
(С теоретической точки зрения - понятно, что такие задачи есть.
Интересуют сколько-нибудь относящиеся к реальной жизни примеры.)
выше предполагается, что все запросы имеют примерно одинаковый вес.
в рельной жизни - запросы к backend`у бывают как очень легкими,
которые отрабатывают за десятые/сотые доли секунды, так и очень
тяжелыми, обработка которых на backend`е занимает несколько секунд
или даже несколько десятков секунд.
в haproxy есть очень изящное решение:
maxconn <maxconn>
maxqueue <maxqueue>
это почти идеальное решение для выравнивания нагрузки на backend,
так чтобы никакой $host не занял 100% ресурсов backend`а,
и в то же время, чтобы не было 503 ошибок при небольшом
и временном всплеске нагрузки на какой-то $host.
например:
maxconn 1
maxqueue 128
или
maxconn 1
maxqueue 1024
с помощью
limit_req<per-host>;
такого плавного выравнивания нагрузки получить нельзя,
потому что backend или будет перегружен "тяжелыми" запросами,
при слишком высоких лимитах или backend будет простаивать,
а клиентов будет отсекать ограничение limit_req<per-host>;
если на $host идет большое количество "легких" запросов
а лимиты limit_req<per-host>; стоят слишком низкие.
более идеальное решение - равномерно распределять запросы
к backend`у из разных очередей, если количество виртуальных
хостов больше, чем количество worker-процессов у backend`а.
т.е. очереди proxy_maxconn/proxy_maxqueue на один и тот же
backend из разных server{ ... } обрабатываются в виде
round-robin и first_in-first_out с учетом лимита maxconn.
(для случая если всплеск нагрузки идет на все/многие $host`ы)
совсем идеальное решение - возможность управлять приоритетами
очередей, примерно как в http://lartc.org/lartc.html
или что-то похожее на maxconn / maxqueue между nginx
и backend`ом можно сделать средствами netfilter,
если подключение к backend`у идет по tcp/ip ?
пока что народ ставит nginx <-> haproxy <-> backend
а если подключение к backend`у идет через
proxy_pass http://unix:/path/to/backend.socket:/uri/;
uwsgi_pass unix:/var/run/example.com.sock;
и т.п. ?
--
Best regards,
Gena
_______________________________________________
nginx-ru mailing list
nginx-ru@xxxxxxxxx
http://mailman.nginx.org/mailman/listinfo/nginx-ru
|