Rate Limiting in Nginx for Complex Configurations: HTTP/2, API and Video Streaming

  • Multiplexing: Multiple queries can be executed on a single connection at the same time.

  • Header compression: Using HPACK for header compression may impact transmission speed.

  • Prioritizing Streams: Clients can set priorities for different streams.

Traffic Shaping Directives in Nginx

limit_rate directive

Limits the speed at which the response is transmitted to the client.

limit_rate rate;
location /downloads/ {
    limit_rate 100k; # Ограничиваем скорость до 100 кБ/с
}

This directive sets the maximum data transfer rate to the client. Useful for limiting the download speed of large files.

limit_rate_after directive

Starts to limit speed after a certain amount of data has been transferred.

limit_rate_after size;
location /videos/ {
    limit_rate_after 5m; # Начинаем ограничивать после 5 МБ
    limit_rate 500k;     # Ограничиваем скорость до 500 кБ/с
}

Can be used when you want to let the user quickly start downloading, and then limit the speed so as not to overload the channel.

Module ngx_http_limit_req_module

Limits the number of requests per second from one client.

limit_req_zone key zone=name:size rate=rate;
  • key: Unique client identifier (usually an IP address).

  • zone: Name and size of memory for storing data.

  • rate: Request rate (eg 10r/s for 10 requests per second).

Example of setup:

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 немедленно отклоняет лишние запросы
        }
    }
}

This setting allows you to protect the API from overload.

Module ngx_http_limit_conn_module

Limits the number of simultaneous connections to one client.

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
        }
    }
}

Good for preventing one user from downloading multiple files at the same time.

Examples of use

Rate limiting for HTTP/2

In HTTP/2, all requests go over one connection, so limit_rate will be applied to all threads at once.

We will use the directive limit_rate inside location or apply dynamic constraints using variables.

map $http_host $limit_rate {
    default 100k; # Устанавливаем ограничение по умолчанию
}

server {
    listen 443 ssl http2;

    location / {
        limit_rate $limit_rate; # Применяем ограничение скорости
    }
}

WITH The variable allows you to flexibly control the speed limit.

Limiting the number of requests for APIs with authentication

Let's say you have an API protected by tokens and you want to limit the number of requests per user.

http {
    limit_req_zone $http_authorization zone=api_limit:10m rate=10r/s;

    server {
        location /api/ {
            limit_req zone=api_limit burst=20 nodelay;
        }
    }
}

Use the title Authorization as a key for user identification.

Traffic management for streaming services

It is necessary to optimize the transfer of large files (video, audio) without loss of quality.

Let's use the module 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 МБ/с
}

Chunking allows for better cache utilization and data transfer control.

Geolocation based restriction

It is necessary to set different speed limits for users from different countries.

Setting up using the module geo:

geo $limit_rate {
    default         500k;    # Ограничение по умолчанию
    192.168.1.0/24  1m;      # Для определённой подсети увеличиваем лимит
    203.0.113.0/24  100k;    # Для другой подсети уменьшаем лимит
}

server {
    location / {
        limit_rate $limit_rate;
    }
}

Optimization and monitoring

Enable Server Status

Allows you to get information about the current state of Nginx:

server {
    location /nginx_status {
        stub_status;
        allow 127.0.0.1; # Разрешаем доступ только с localhost
        deny all;
    }
}

Access to this page will help you monitor active connections and process data in monitoring systems.

Setting up logging

Add information about the limitation to the logs:

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;

Field $limit_req_status will show the restriction status PASSED, DELAYED, REJECTED.


Conclusion

Setting up full-fledged traffic shaping in Nginx is not an easy task, but it is extremely important. It requires attention to detail and understanding of the specifics of each case.

Also, taking this opportunity, I would like to remind you about the open lesson on the basics of load balancing in Angie and Nginx, which will take place today (September 16) at 19:00.

In this lesson, we will get acquainted with the architecture of load balancing in web applications, consider various methods of load balancing in Nginx and Angie, the differences in these products. We will also talk about fault tolerance. You can sign up for the lesson on the Nginx/Angie Administration course page.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *