Nginx ограничение нагрузки

Вещь о которой я хочу написать довольно тривиальна, но вдруг кому-то будет полезна.

В Nginx есть модуль ngx_http_limit_req_module. Данный модуль позволяет ограничивать количество и частоту запросов к сайту с одного IP-адреса.
Возьмем в качестве примера следующий конфиг
http {
    limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

    ...

    server {

        ...

        location /search/ {
            limit_req zone=one burst=5;
        }
Здесь мы указываем, что сайт будет обрабатывать 1 запрос в секунду с одного IP-адреса. Но при этом позволяется по ссылке /search/ делать до 5 запросов в секунду. При превышении данных ограничений пользователь увидит ошибку 503.

Есть одна тонкость. Вы можете делать до 5 запросов, но запросы будут обрабатываться по 1 в секунду. Если вы хотите чтобы они обрабатывались без задержки необходимо указать в limit_req дополнительный ключ nodelay.

Конечно данная настройка вас не защитит от ддос атак, но от пользователя с зажатой клавишей обновления страницы точно спасет.

Похожие статьи

  • Makersbay.ru – каталог 3d моделей для 3d принтера
    Мне всегда нравилось делать что-то своими руками и мастерить, поэтому я и не смог пройти мимо такой вещи как 3d принтер. Купил себе принтер и заодно сделал и сайт с 3d моделями для онного. Выбрал я Altocms и в...
  • Установка в подкаталог
    Уже поднимались подобные темы, но у меня несколько иная ситуация. Имеем nginx+php-fpm, livestreet 1.0.3 (позже будет ясно зачем), alto 0.9.7.1. Хочу установить alto в подкаталог, относительно корня. В корне одна cms, ...
  • Установка и настройка Nginx+Apache на сервере для Alto CMS
    disclaimer: Все настройки приведенные в данной статье проверены мной на рабочем сервере, но они не являются единственно верным решением, по сему любые дополнения, примеры ваших конфигов и дельные советы...
  • Использование кукисов, проблемы кеширования nginx
    Цель данной заметки: Решить проблему кеширования на уровне nginx. Предисловие: Кешировать можно все страницы на 10-60 минут для не залогиненных пользователей. Проверять залогиненных пользователя можно по куке (LS —...

5 комментариев

0
Бессмысленная накрутка. Повторные запросы должны отдаваться используя кеши. А уж сколько раз пользователь нажмет на рефреш — сугубо его прихоть. Хоть 100. Если из-за этого сервис встает колом, то можно собирать вещи и сворачиваться, ибо это нонсенс. Видеть 503 ответ — тоже нонсенс. Зачем мне такой сервис? А из-за использования NAT`а провайдерами из под одного IP может ходить сколько угодно пользователей.
Отредактирован:
0
1. А зачем сервису такой пользователь, который делает 20 запросов в секунду? Ну явно не обычный пользователь.

2. Вы кэшируете всю страницу целиком или только объекты используемые для генерации страницы? Сколько времени генерируется у вас хотя бы главная страница? Или же у вас закэшированный html отдается?

3. Если страница генерируется, даже за 0.1 секунды, вы же понимаете что это довольно ощутимая нагрузка для впс. Если я в 10 закладках поставлю отправлять 50 запросов в секунду? Мой впс может и потянет, но отдавать страницы ооооочень долго.

4.Даже habrahabr использует этот же инструмент. Вы этим сайтом тоже не пользуетесь потому что он отдает 503?
0
1. А зачем сервису такой пользователь, который делает 20 запросов в секунду? Ну явно не обычный пользователь.

А зачем сервису который можно положить с одного IP вообще думать о высокой нагрузке? Видимо он расчитан изначально на другое.

И сразу второй, зачем севис рассчитанный на 10 юзеров в день кто-то будет ддосить? =) И кто этот человек пользующийся таким МОЩНЫМ инструментом? =)

2. Вы кэшируете всю страницу целиком или только объекты используемые для генерации страницы? Сколько времени генерируется у вас хотя бы главная страница? Или же у вас закэшированный html отдается?

Кеширование в высоконагруженных проектах всегда многослойное — что-то должно кешироваться ну уровне браузера, что-то на уровне веб сервера, что-то на уровне логики, что-то на уровне БД, и т.д.

В контексте Альто, достаточно включить query cache на InnoDB в MySQL чтобы повторные селекты не приводили к повторным обращениям к дисковой подсистеме, а результаты брались из памяти. Даже мемкеш не нужен.

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

3. Если страница генерируется, даже за 0.1 секунды, вы же понимаете что это довольно ощутимая нагрузка для впс. Если я в 10 закладках поставлю отправлять 50 запросов в секунду? Мой впс может и потянет, но отдавать страницы ооооочень долго.

Пользователи обновляющие страницу создают очень малую нагрузку.

4.Даже habrahabr использует этот же инструмент. Вы этим сайтом тоже не пользуетесь потому что он отдает 503?

Высоконагруженные проекты уровня хабра скажем так чуть более сложную архитектуру имеют.
0
Я не говорю что один человек может положить сайт, ни разу не говорил. Но от возросшей нагрузки сайт будет медленнее работать для остальных пользователей.

Даже если у сайта аудитория 100 человек, ну можно же банально защититься от одного обиженного человека? Можно. Всего-то две строки в конфиге. Станет ли от этого проекту хуже? На мой взгляд нет.

В контексте Альто, достаточно включить query cache на InnoDB в MySQL чтобы повторные селекты не приводили к повторным обращениям к дисковой подсистеме, а результаты брались из памяти. Даже мемкеш не нужен.
В альто, по крайней мере у меня, наибольшую нагрузку дают не запросы к базе. Вот практически голый сайт с альто у меня генерируется 0.05 секунды, из них обращение к базе и кэшу занимает 0.0015, смешное время. Т.е. эти самый 0.05 с процессор над чем-то трудится. Обрабатывает экшены, ивенты, условия и циклы в смарти. Сколько будет обращений к странице столько процессор и будет заниматься вычислениями и будет нагружен.
Пользователи обновляющие страницу создают очень малую нагрузку.
Давайте проверим. Возьмем хром, откроем ваш сайт и в консоле запустим
for (var i = 0; i < 2000; i++) {
 ls.ajaxGet("http://yourdomain.ru/", {}, null);
}
Запустим мониторинг, хотя бы top, на сервере и понаблюдаем за нагрузкой. У вас нагрузка не возросла? У меня её отчетливо видно. Правда в других браузерах сайт отвечает, и не всегда задумчиво, но мы видим пожирание ресурсов.

Нет, я ни в коем случае не говорю что это панацея, нет. Просто почему бы и нет. Я в нем вижу больше пользы чем вреда.
0
В альто, по крайней мере у меня, наибольшую нагрузку дают не запросы к базе. Вот практически голый сайт с альто у меня генерируется 0.05 секунды, из них обращение к базе и кэшу занимает 0.0015, смешное время.

Если включен кеш так и будет. Или это вообще пустой сайт, на котором ничего не создается. Посмотрим что случится, когда будут одновременно и инсерты и апдейты и селекты идти.

БД — с наибольшей вероятностью главная проблема. Если конечно не используется апач с префорком. (Тогда и нагрузку создавать не надо достаточно открыть N медленных соединений, заблокировав все ресурсы веб сервера).

Запустим мониторинг, хотя бы top, на сервере и понаблюдаем за нагрузкой. У вас нагрузка не возросла? У меня её отчетливо видно. Правда в других браузерах сайт отвечает, и не всегда задумчиво, но мы видим пожирание ресурсов.

Мой сайт сейчас не на альто, он расчитан небольшую нагрузку. VPS за 500 р в месяц. При 50 одновременных клиентах, и времени загрузки ~0.9-1 (методика loadimpact.com) никакой существенной нагрузки на ЦПУ я не наблюдал, как и деградации сервиса. Если потребуется что-то более серьезное — я начну с анализа трафик модели и узких мест, таки думаю этим местом будет БД, а если точнее — дисковая подсистема по iops.

Самая основная проблема такого фильтра что из под одного IP могут приходить несколько пользователей. Значит надо это закладывать. Если это закладывать, то сама эта идея теряет смысл, а способов ДоСа и ДДоСа в целом куда больше.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.