Nginx bandwidth control (used by speed limiting module)

  • 2020-05-09 19:54:08
  • OfStack

There was an old project that offered file downloading via Squid and bandwidth control via delay_parameters. The problem was that I couldn't play with Squid, so I wondered if I could find something similar in Nginx.


The good news is that Nginx provides limit_rate and limit_rate_after, for example:


location /download/ {
    limit_rate_after 500k;
    limit_rate 50k;
}

After reaching 500k, the user controls the speed within 50k.

The bad news is that this control is for a single connection. In other words, you can limit the bandwidth of a single connection, not the total bandwidth. However, using the limit_conn module can alleviate the problem to a certain extent:


limit_conn_zone $server_name zone=servers:10m; server {
    location /download/ {
        limit_conn servers 1000;
        limit_rate_after 500k;
        limit_rate 50k;
    }
}

By limiting the number of concurrent connections through limit_conn, you limit the total bandwidth. Unfortunately, this is not a perfect solution. Consider the following example: 1000 users can download at 50k at the same time; Can 2000 users download at 25k at the same time with the same total bandwidth? From a business perspective, the answer is naturally yes, but in practice limit_conn and limit_rate are not flexible enough to simply implement such logic.

Of course, there must be a solution to the problem. For example, use the third module: limit_speed; You can also use Linux's built-in TC command. limit_speed is easy, so let's look at the usage of TC:


shell> tc qdisc add dev eth0 root handle 1: htb default 10
shell> tc class add dev eth0 parent 1: classid 1:1 htb rate 10mbit
shell> tc filter add dev eth0 protocol ip parent 1:0 prio 1 \
       u32 match ip dport 80 0xffff flowid 1:1


The complexity of TC drives people crazy. See Linux Advanced Routing & Traffic Control HOWTO.

This paper introduces several modules of Nginx for restricting access, and actually there is one limit_req module which is also excellent. Although it is not relevant to this paper, it is recommended that you should know about it, and you can refer to "nginx limit_req speed limit setting" for details.


Related articles: