Привет, Хабр!
Сегодня рассмотрим, как настроить полноценный traffic shaping в Nginx для сложных случаев, включая HTTP/2.
С появлением HTTP/2 управление трафиком стало ещё сложнее из-за его особенностей:
-
Мультиплексирование: Несколько запросов могут выполняться по одному соединению одновременно.
-
Сжатие заголовков: Использование HPACK для сжатия заголовков может влиять на скорость передачи.
-
Приоритизация потоков: Клиенты могут устанавливать приоритеты для разных потоков.
Директивы Traffic Shaping в Nginx
Директива limit_rate
Ограничивает скорость передачи ответа клиенту.
limit_rate rate;
location /downloads/ { limit_rate 100k; # Ограничиваем скорость до 100 кБ/с }
Эта директива устанавливает максимальную скорость передачи данных клиенту. Полезно для ограничения скорости загрузки больших файлов.
Директива limit_rate_after
Начинает ограничивать скорость после передачи определённого объёма данных.
limit_rate_after size;
location /videos/ { limit_rate_after 5m; # Начинаем ограничивать после 5 МБ limit_rate 500k; # Ограничиваем скорость до 500 кБ/с }
Можно использовать, когда нужно дать пользователю быстро начать загрузку, а затем ограничить скорость, чтобы не перегружать канал.
Модуль ngx_http_limit_req_module
Ограничивает количество запросов в секунду от одного клиента.
limit_req_zone key zone=name:size rate=rate;
-
key: Уникальный идентификатор клиента (обычно IP-адрес).
-
zone: Имя и размер памяти для хранения данных.
-
rate: Скорость запросов (например, 10r/s для 10 запросов в секунду).
Пример настройки:
http { limit_req_zone $binary_remote_addr zone=mylimit:10m rate=5r/s; server { location /api/ { limit_req zone=mylimit burst=10 nodelay; # burst=10 позволяет временно превышать лимит на 10 запросов # nodelay немедленно отклоняет лишние запросы } } }
Эта настройка позволяет защитить API от перегрузки.
Модуль ngx_http_limit_conn_module
Ограничивает количество одновременных соединений с одним клиентом.
limit_conn_zone key zone=name:size;
http { limit_conn_zone $binary_remote_addr zone=addr:10m; server { location /download/ { limit_conn addr 1; # Разрешаем только 1 соединение с одного IP } } }
Хорошо для предотвращения одновременной загрузки нескольких файлов одним пользователем.
Примеры использования
Ограничение скорости для HTTP/2
В HTTP/2 все запросы идут по одному соединению, поэтому limit_rate
будет применяться ко всем потокам сразу.
Будем использовать директиву limit_rate
внутри location
или применять динамическое ограничение с помощью переменных.
map $http_host $limit_rate { default 100k; # Устанавливаем ограничение по умолчанию } server { listen 443 ssl http2; location / { limit_rate $limit_rate; # Применяем ограничение скорости } }
С переменной можно гибко управлять ограничением скорости.
Ограничение количества запросов для API с аутентификацией
Допустим, есть API, защищённый токенами, и нужно ограничить количество запросов для каждого пользователя.
http { limit_req_zone $http_authorization zone=api_limit:10m rate=10r/s; server { location /api/ { limit_req zone=api_limit burst=20 nodelay; } } }
Используем заголовок Authorization
в качестве ключа для идентификации пользователя.
Управление трафиком для стриминговых сервисов
Необходимо оптимизировать передачу больших файлов (видео, аудио) без потери качества.
Используем модуль slice
:
location /video/ { slice 1m; # Разбиваем файл на куски по 1 МБ proxy_pass http://backend; proxy_set_header Range $slice_range; limit_rate_after 10m; # Ограничиваем скорость после 10 МБ limit_rate 1m; # Ограничиваем скорость до 1 МБ/с }
Разбивка на куски позволяет лучше использовать кэш и управлять передачей данных.
Ограничение на основе геолокации
Нужно установить разные ограничения скорости для пользователей из разных стран.
Настройка с использованием модуля geo
:
geo $limit_rate { default 500k; # Ограничение по умолчанию 192.168.1.0/24 1m; # Для определённой подсети увеличиваем лимит 203.0.113.0/24 100k; # Для другой подсети уменьшаем лимит } server { location / { limit_rate $limit_rate; } }
Оптимизация и мониторинг
Включение статуса сервера
Позволяет получить информацию о текущем состоянии Nginx:
server { location /nginx_status { stub_status; allow 127.0.0.1; # Разрешаем доступ только с localhost deny all; } }
Доступ к этой странице поможет мониторить активные соединения и обрабатывать данные в системах мониторинга.
Настройка логирования
Добавляем информацию о лимитировании в логи:
log_format custom '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" ' '$limit_req_status'; access_log /var/log/nginx/access.log custom;
Поле $limit_req_status
покажет статус ограничения PASSED
, DELAYED
, REJECTED
.
Заключение
Настройка полноценного traffic shaping в Nginx — задача непростая, но крайне важная. Она требует внимания к деталям и понимания особенностей каждого случая.
Также, пользуясь случаем, напоминаю про открытый урок по основам балансировки нагрузки в Angie и Nginx, который пройдет сегодня (16 сентября) в 19:00.
На занятии познакомимся с архитектурой балансировки нагрузки в веб-приложениях, рассмотрим различные методы балансировки нагрузки в Nginx и Angie, различия в этих продуктах. А также поговорим об отказоустойчивости. Записаться на урок можно на странице курса «Администрирование Nginx/Angie».
ссылка на оригинал статьи https://habr.com/ru/articles/843424/
Добавить комментарий