The Surrican
The Surrican

Reputation: 29864

How can I limit a users total bandwidth across multiple webservers and connections?

I have a web-service where users download files tunneled via apache2 reverse proxies.

I am using mod rewrite and the P flag in conjunction with a rewrite map.

Basically it looks like this:

<Location /my-identifier>
    RewriteEngine on
    RewriteRule /my-identifier/(.*) ${my-rewrite-map:$1} [P]
</Location>

I know I can limit the bandwidth of one connection or even one ip-address per server using mod_bandwidth or something similar.

However I want the limit to take effect only for certain users (namely those who make a lot of traffic and exceeded the fair use volumes).

I also want it to span across multiple servers.

It is possible for me to set a custom environment variable, if that helps (I have full control over the URL where I can encode it into and can set it using the rewrite rule)!

Basically what I want is for example for a user who reached their limit to get only 5 mbps of speed, no matter how many connections they use or how many servers they connect to.

Is it somehow possible? Is there a module?

My thought would be a centralized data-store where the servers report their traffic stats per ip to. Probably some sort of RRD data structure. Then they can select the traffic for the ip over a specified time interval (for example the last 60 seconds) and apply a throttle factor according to it.

But I really don't want to do this all by myself, I could but it would take me months... I am also not bound to apache. I am also using Nginx servers for the same thing, if there is something for Nginx I can switch to it!

Upvotes: 1

Views: 3174

Answers (1)

cobaco
cobaco

Reputation: 10546

I don't know about Apache, but since you listed Nginx as a tag, how about something like the approach below?

Set up Nginx as a reverse proxy to your Apache servers or web-services with more or less the following configuration:

upstream serverlist {
  server www1.example.com;
  server www2.example.com;
  server www3.example.com;
}

location / {
  proxy_pass http://serverlist;
}

The "overall connections" requirement you have is not directly mappable, but you can probably get reasonably close to what you want with a combination of the following directives added to the location block:

  • limit_rate this is per connection
  • limit_con this allows you to limit the number of connections
  • limit_req this allows you to limit the number of requests/sec and allowable bursts
  • limit_zone sets up the zone for your limits

UPDATE: There's a 3th party Nginx module limiting the overall rate per IP to be found here.

Upvotes: 1

Related Questions