Nginx Current Limiting Configuration

Posted by hismightiness on Tue, 21 Apr 2020 02:00:14 +0200

  1. Current Limiting Algorithm

    1. Token Bucket

      Tokens are generated at a fixed rate and placed in the token bucket. When the token bucket is full, extra tokens are discarded; requests consume an equal proportion of tokens.When the token is not enough, the request comes and no token is received, and the request is denied service.

    2. Leaky bucket algorithm

      A request is like a flow of water.Water flows out of the bucket at a fixed speed from above to inside.When the water above is too large to flow out of the bucket, the water will be temporarily cached in the bucket.When the water is too large, the bucket will overflow when it is full (the overflow is equivalent to a discard request)

    While the Leaky Bucket algorithm can force the rate of data transfer, the Token Bucket algorithm allows some burst transmission in addition to limiting the average rate of data transfer (in extreme cases, browsing explodes when the tokens in the bucket are full).

  2. Current Limiting Configuration

    1. limit_req_zone

      The leaky bucket algorithm used to limit the number of requests per unit time, i.e. rate limit, is leaky bucket.

      limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
      //$binary_remote_addr means that the limit is made by the identity remote_addr, and the purpose of binary_ is to abbreviate the memory footprint and limit the ip address of the same client.
      //zone=one:10m means that a memory area of 10M in size and one in name is generated to store the frequency information accessed.
      //rate=1r/s denotes that clients with the same identity are allowed access frequency, which is limited to one per second, and can be as high as 30r/m.
      
      limit_req zone=one burst=5 nodelay;
      //zone=one sets which configuration area to use to restrict, corresponding to the name in limit_req_zone above.
      //burst=5, set a buffer size of 5. When a large number of requests (bursts) come in, requests that exceed the access frequency limit can be placed in this buffer first.
      //nodelay, if set, returns 503 directly when the access frequency is exceeded and the buffer is full. If not set, all requests are queued.
      
      //Example:
      http {
      	limit_req_zone $binary_remote_addr zone = one: 10 m rate = 1 r / s;
      	server {
      		location / search / {
      			limit_req zone = one burst = 5 nodelay;
      		}
      	}
      }
      
      // The following configurations can restrict access to specific UA s, such as search engines
      http{
      	limit_req_zone $anti_spider zone = one: 10 m rate = 10 r / s;
      	limit_req zone = one burst = 100 nodelay;
      	if ($http_user_agent~ * "googlebot|bingbot|Feedfetcher-Google") {
      		set $anti_spider $http_user_agent;
      	}
      }
      

      Other parameters:

      Syntax:    limit_req_log_level info | notice | warn | error;   
      Default:   limit_req_log_level error;    
      Context:    http, server, location
      //Set the level of logging you want, which you can write down when the server rejects or delays processing requests because of high frequency.The log level for deferred logging is one level lower than that for rejection; for example, if limit_req_log_level notice is set, the deferred log is the info level.
      
      Syntax:  limit_req_status code;    
      Default: limit_req_status 503;    
      Context: http, server, location
      //Set the return value for rejecting requests to be between 400 and 599.
      
    2. limit_req_conn

      Used to limit the number of requests for a single IP.Not all connections are counted.Connections are counted only if the server processes the request and has read the entire request header.

      Syntax:    limit_conn_zone key zone=name:size;   
      Default:    —    
      Context:    
      // Note: the value of key is $binary_remote_addr instead of $remote_addr; refer to the official documentation: http://nginx.org/en/docs/http/ngx_http_limit_conn_module.html#limit_conn_zone
      
      Syntax:    limit_conn zone number;    
      Default:    —    
      Context:    http, server, location    
      
      // Allow only one connection per IP address at a time
      limit_conn_zone $binary_remote_addr zone=addr:10m;
      server {
      	location /download/ {         
            	limit_conn addr 1;       
            }
      }
      
      //Limit the number of IP connections per client to the server to 10, while limiting the total number of connections to the virtual server to 100
      limit_conn_zone $binary_remote_addr zone=perip:10m;    
      limit_conn_zone $server_name zone=perserver:10m;
      server {       
        		...        
          	limit_conn perip 10;        
        	limit_conn perserver 100;    
      }
      

      Other configurations:

      // Set the required logging level when the server limits the number of connections
      Syntax: limit_conn_log_level info | notice | warn | error;    
      Default: limit_conn_log_level error;    
      Context: http, server, location
      
      // Set status code to return in response to a rejected request
      Syntax:    limit_conn_status code;    
      Default:   limit_conn_status 503;    
      Context:    http, server, location
      
  3. Configuration example:

    1. Restrict access rate

      limit_req_zone $binary_remote_addr zone=mylimit:10m rate=2r/s;    
      server {         
      		location / {             
      				limit_req zone=mylimit;        
      		}    
      }
      

      This configuration limits the processing of requests to two times in 1 s, once in 500ms

    2. burst cache processing

      limit_req_zone $binary_remote_addr zone=mylimit:10m rate=2r/s;    
      server {         
        location / {             
          limit_req zone=mylimit burst=4;        
        }    
      }
      

      burst=4 means that each key (here, each IP) allows up to four burst requests to arrive.If a single IP sends six requests within 10 ms, one request is processed immediately, four requests are cached, and one request is discarded.Four requests are placed in the burst queue. The worker process takes one request every 500ms(rate=2r/s) to process, and the last request queues for 2s before it is processed.

      Note: burst is used to allow unwanted requests to be queued first and processed slowly.Without the nodelay parameter, requests in the queue are not processed immediately, but rather slowly and accurately in milliseconds at the rate set.

    3. nodelay reduces queue time

      limit_req_zone $binary_remote_addr zone=mylimit:10m rate=2r/s;    
      server {         
        location / {             
          limit_req zone=mylimit burst=4 nodelay;        
        }    
      }
      

      The nodelay parameter allows requests to be processed immediately when queued, that is, whenever a request can enter the burst queue, it will be processed immediately by the background worker. Note that this means that when burst sets a nodelay, the instantaneous QPS of the system may exceed the threshold set by rate.The nodelay parameter is useful only if it is used with burst.

      When a single ip comes over 6 requests in 10ms, the success rate is the same as above, with 5 requests succeeding and 1 request failing.Requests in the queue are eligible to be processed at the same time, and it takes less time to process as if five requests were started at the same time.

      Note: Although setting burst and nodelay can reduce the processing time of burst requests, it will not increase the upper limit of throughput in the long run. The upper limit of long-term throughput is determined by rate, because nodelay can only guarantee that burst requests are processed immediately, but Nginx limits the speed at which queue elements are released, just as it limits the speed at which tokens are generated in the token bucket.

    4. Custom Return Value

      limit_req_zone $binary_remote_addr zone=mylimit:10m rate=2r/s;   
      server {         
        location / {            
          limit_req zone=mylimit burst=4 nodelay;            
          limit_req_status 598;        
        }    
      }
      

      This way, when the request exceeds the set threshold, the status code returned is 598

Note:

  1. Reference article: How to use Nginx restriction gracefully

  2. Learn about articles: Nginx Source Code Notes - HTTP Module - Flow Control

  3. It is not easy to organize. If you need to reproduce it, please indicate the source: https://www.cnblogs.com/zhuchenglin/p/12741299.html

Topics: Nginx Google less