Nginx Limited Current Actual Warfare

Keywords: Java Nginx network Spring

In the current era of high concurrency of the Internet, projects often encounter the need to restrict client connections.The well-known Nginx provides the ability to simply limit the frequency of client requests, concurrent connections, and transfer speeds....

Nginx Current Limit

Nginx provides us with a request restriction module (ngx_http_limit_req_module), a traffic restriction module based on the token bucket algorithm (ngx_stream_limit_conn_module), which can easily control the token rate, customize the current restriction, and implement basic current restriction control.

Request Restrictions

The function of request restriction comes from the ngx_http_limit_req_module.To use it, you first need to define a restricted reference standard and state cache size in the HTTP configuration section.

limit_req_zone can only be configured in the http range;

$binary_remote_addr represents the IP address requested by the client;

mylimit's own variable name;

rate Request frequency, how many requests are allowed per second;

Limit_req corresponds to limit_req_zone, where burst indicates the number of cached requests, or task queues.

The following configuration defines the use of the client's IP as a reference and uses a 10M state cache.rate=1r/s at the end indicates that requests for each IP are accepted only once per second.

Is 10M of state cache space not enough?The official answer is that 1M of cache space can service 32,000 IP addresses on 32-bit systems and 16,000 IP addresses on 64-bit systems, so you need to adjust it yourself.If the state cache runs out, all subsequent requests will receive a 503(Service Temporarily Unavailable) error.

Script Code

# A mylimit buffer (container) is defined with a request frequency of 1 request per second (nr/s)
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=1r/s;
server {
listen  70;
location / {
# nodelay does not delay processing
# burst is configuring overhandling and can be simply understood as a queue mechanism
# The above configuration configures the same IP to send only one request per second (1r/s), where three requests are cached, which means that only four tasks are allowed to respond successfully in the same second, while other task requests fail (503 error).
limit_req zone=mylimit burst=3 nodelay;
proxy_pass http://localhost:7070;
}
}

Test Code

For the convenience of providing JAVA, AB test code here..

# -n is the total number of times a specified stress test has been executed
# -c is the specified number of concurrencies
ab -n 5 -c 5 http://192.168.0.133:70/index
package com.battcn.limiting;

import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author Levin
 * @since 2018/7/27 0027
 */
public class NginxLimiterTest {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService service = Executors.newFixedThreadPool(5);
        for (int i = 0; i < 6; i++) {
            CompletableFuture.supplyAsync(() -> {
                final ResponseEntity<String> entity = new RestTemplate().getForEntity("http://192.168.0.133:70/index", String.class);
                return entity.getBody();
            }, service).thenAccept(System.out::println);
        }
        service.shutdown();
    }
}

Test log

A log of the AB test result JAVA is not pasted here. One of the five requests is problematic. The one that is problematic is the one that was rejected.

[root@localhost myconf]# ab -n 5 -c 5 http://192.168.0.133:70/index
Document Path:          /index
Document Length:        34 bytes

Concurrency Level:      5
Time taken for tests:   0.002 seconds
Complete requests:      5
Failed requests:        1
   (Connect: 0, Receive: 0, Length: 1, Exceptions: 0)

Concurrency restrictions

Nginx concurrency restriction comes from the ngx_http_limit_conn_module module, which, like request configuration, requires defining reference standards and state caches before using it.

limit_conn_zone can only be configured in the http range;

$binary_remote_addr represents the IP address requested by the client;

myconn's own variable name (buffer);

limit_rate limits transmission speed

Limit_conn corresponds to limit_conn_zone, limiting the number of network connections

The following configuration defines the use of the client's IP as a reference and uses a 10M state cache.Limited to allow only one request connection per IP, with a maximum transfer speed of 1024 KB

Script Code

# A myconn buffer (container) is defined
limit_conn_zone $binary_remote_addr zone=myconn:10m;
server {
listen  70;
location / {
# Only one connection per IP is allowed
limit_conn myconn 1;
# Limit transfer speed (N * limit_rate if there are N concurrent connections)
limit_rate 1024k;
proxy_pass http://localhost:7070;
}
}

Say something

Request streaming restriction write a simple Spring Boot program to deploy to the server, configure the Nginx mapping, and then limit the streaming to get a large file download, or allow your service interface to sleep for a certain time to test the effect....

Posted by cetaces on Sat, 10 Aug 2019 16:20:51 -0700