Nginx load balancing-expansion function (NGINX Plus), nginx Load Balancing
Nginx load balancing-expansion feature (NGINX Plus). This article mainly introduces the functions of NGINX Plus, and updates across different versions such as NGINX Plus R5, R6, R7, and R9.
What is NGINX Plus?
As the name suggests, it is the enhanced or extended version of Nginx. We know that Nginx is open-source and free of charge, but charges are required for many functions of NGINX Plus. Nginx Plus can be used as a Load balancer, a web server, and a content cache. Since it is an enhanced version of Nginx, it will undoubtedly be more powerful than Nginx. Based on the existing functions of open-source NGINX, Nginx Plus provides many proprietary functions suitable for the production environment, including session consistency, real-time update API configuration, and effective health check.
NGINX Plus version update
NGINX Plus R5 and later versions support TCP application-based load balancing (such as MySQL ). This not only limits Http load balancing, but also greatly expands the scope of Nginx as a Load balancer. In R6, the TCP load balancing function has been greatly expanded, including health check, Dynamic Update Configuration, and SSL terminal. When R7 is reached, the TCP load balancing function is basically similar to Http load balancing. After z reaches R9, UDP can be supported. Through these updates, NGINX Plus far exceeds the web application layer and has becomeMore extensive Load balancer. After all, the Protocol is a basic layer. The more protocols supported, the wider the application. From the initial Http/SMTP to TCP to UDP, NGINX Plus is becoming more and more powerful step by step.
Both open-source Nginx and NGINX Plus Support HTTP, TCP, and UDP application load balancing. However, NGINX Plus provides enterprise-level functions that are charged, including session consistency, health check, and dynamic configuration update.
HTTP Load Balancing
NGINX Plus optimizes Http Server Load balancer in many functions, such as HTTP upgrade, persistent connection optimization, content compression, and response caching. The implementation of Http load balancing in NGINX Plus is also very simple:
http { upstream my_upstream { server server1.example.com; server server2.example.com; } server { listen 80; location / { proxy_set_header Host $host; proxy_pass http://my_upstream; } }}
You can use the proxy_set_header command to set the Host, and proxy_pass forwards the request to the upstream my_upstream.
Http Keepalives)
HTTP uses the underlying TCP protocol to transmit requests and receive responses. HTTP1.1 supports TCP persistent connections or reuse to avoid overhead caused by repeated creation and destruction of TCP connections.
Let's take a look at the Http persistent connection:
NGINX is a completely reverse proxy, which is also unambiguous in long connections. It manages persistent connections from clients to Nginx and also manages persistent connections from Nginx to upstream servers. The two are completely independent.
Persistent connections managed by Nginx:
NGINX caches idle connections to upstream servers and does not directly turn them off. If a request comes in, NGINX first obtains a usage from the active connection of the cache, instead of creating a new one immediately. If the cache is empty, NGINX then creates a new connection. This operation reduces the latency between Nginx and upstream servers and reduces the utilization of temporary ports. Therefore, NGINX can handle high concurrency. This technology, coupled with other load balancing technologies, is sometimes calledConnection Pool, Or connection reuse.
To configure the idle persistent connection cache, You need to specify several commands: proxy_http_version, proxy_set_header, keepalive
Server {listen 80; location/{proxy_pass http: // backend; proxy_http_version 1.1; # persistent Connection proxy_set_header Connection "";} upstream backend {server webserver1; server webserver2; # maintain a maximum of 20 idle connections to each upstream server keepalive 20; # idle long connection cache time is 20}
TCP and UDP Load Balancing
As an extension of the Http protocol, NGINX Plus can directly support TCP and UDP-based applications. TCP-based applications such as MySQL support UDP such as DNS and RADIUS. For TCP requests, NGINX Plus receives TCP requests from the client, and then creates a TCP request to initiate an access to the upstream server.
Stream {upstream my_upstream {server server1.example.com: 1234; server server2.example.com: 2345;} server {listen 1123 [udp]; proxy_pass my_upstream; # note that http: // is not found here }}
TCP requests are supported in NGINX Plus R5. The R6 and R7 versions are mainly optimizing this function. By R7, the load balancing of TCP requests is powerful enough to rival Http load balancing, in R9, UDP is supported. Here, I will first make an impression that the TCP load balancing function will be introduced in more detail later.
Connection Limiting)
You can also limit the number of connections for Server Load balancer. The connection here refers to the Http/TCP/UDP request connection that NGINX Plus sends to the upstream server (for UDP, It is a session ). With the connection limit function, when the number of Http/TCP connections of the upstream server or the number of UDP sessions exceeds a certain value, NGINX Plus will not create a new connection or session. The extra request connections on the client can be put into the queue or not processed. You can useMax_conns, queueCommand to achieve this:
upstream backend { zone backends 64k; queue 750 timeout=30s; server webserver1 max_conns=250; server webserver2 max_conns=150;}
The server command indicates that webserver1 can host a maximum of 250 connections while webserver2 can host a maximum of 150 connections. The extra commands can be placed in the queue for waiting. The number of connections waiting in the queue and the waiting time are also limited. When the number of webserver1 and webserver2 connections is reduced to below the maximum number of connections, wait for the connections in the queue to be filled up at any time.
Queue 750 timeout = 30s indicates that a total of 750 connections can be queued up, and each connection waits for 30 s.
Limiting connections is very useful and can provide clients with sustainable and foreseeable services-it is not necessary to fail due to a large server load. Generally, the load that a server can carry can be tested by some means. Therefore, taking the tolerable launch as the value of the max_conns command can ensure the relative security of the server.
Least Time Load Balancing Algorithm
In NGINX Plus R6, a new balancing algorithm, Least Time, is added to take the corresponding Time into account, which is equivalent to the extension of Least Connections.
This algorithm takes into account the current number of connections and the average response time of each node in the connection pool. The purpose is to make the current request select the currentFaster response and fewer connectionsInstead of selecting a server with slower response and more connections.
When each server node in the connection pool has a significantly different response latency, this algorithm is better than other nodes (round-robin/ip-hash/lease connections ). A typical application scenario is that if there are two data centers distributed in different regions, the local data center will have a much lower latency than the remote data center, in this case, the number of current connections cannot be considered, and the latency of this response must also be considered. The Least Time algorithm tends to be local. Of course, this is just a "more inclined" problem. It cannot replace the most basic error transfer function of Nginx, even if the local data center responds faster, if Nginx Plus fails, it can be immediately switched to the remote data center.
The "minimum time" can be calculated in two ways: one is the time calculated from the request sent to the upstream server and the response header is returned, the other is the time from the time when the request is sent to the time when it receives all the request bodies, expressed in header_time and response_time respectively.
Session Persistence)
Session consistency can be achieved by specifying the ip-hash balancing algorithm, as well as a more general implementation method, which is implemented in NGINX Plus.
NGINX Plus can identify user sessions, so as to identify different clients and send requests from the same client to the same upstream server. This is very useful when the application saves the user status, and can avoid the Server Load balancer sending requests to other servers according to a certain algorithm. In addition, this method is also very useful for cluster servers that share user information.
Session consistency requires that the same server be selected for each request from the same client. Server Load balancer requires us to use an algorithm to select the next server connection pool, can these two conflicting methods coexist? Yes. follow the steps below to determine which one to choose for NGINX Plus:
If the request matches a Session consistency rule, select the upstream server based on the Rule. If no matching or matching server is unavailable, use the Server Load balancer algorithm to select the upstream server;
To ensure session consistency, Nginx Plus provides sticky cookie, sticky learn, and sticky route rules.
Sticky cookie rules
For sticky cookie rulesFirstWhen the request selects an upstream server and returns an response from the upstream server, NGINX Plus adds a session cookie for the response to identify the upstream server. When subsequent requests are sent, NGINX Plus extracts the cookie, analyzes the server, and sends the request to the same server.
Use the command sticky cookie and configure it as follows:
upstream backend { server webserver1; server webserver2; sticky cookie srv_id expires=1h domain=.example.com path=/; }
The cookie name is srv_id, which is used to "remember" which server is used; the expiration time is 1 h, the domain is .example.com; the path is/
In the first response, NGINX Plus inserts a cookie named srv_id to "remember" The upstream of the first request, and the subsequent request carries the cookie, it is also checked by NGINX Plus and then sent to the same server. This ensures session consistency.
Sticky route rules
Similar to the sticky cookie rule, the method of "Remembering" an upstream server is different.
When the client initiates the first request, the server that receives the request assigns a route to it. After that, all the requests initiated by the client must carry the route information, either in the cookie or in the uri. Then compare with the route parameter in the server command to decide which server to select. If the specified server cannot be processed, the Server Load balancer algorithm is used to select the next server.
map $cookie_jsessionid $route_cookie { ~.+\.(?P
\w+)$ $route;}map $request_uri $route_uri { ~jsessionid=.+\.(?P
\w+)$ $route;}upstream backend { server backend1.example.com route=a; server backend2.example.com route=b; # select first non-empty variable; it should contain either 'a' or 'b' sticky route $route_cookie $route_uri;}
Here, route is selected in the cookie of JSESSIONID. If route contains a, select backend1 for the server; if route contains B, select backend2 for the server; if route does not contain B, make a similar choice in $ request_uri, and so on.
No matter which method you choose to keep the session consistent, if the selected server cannot be used, the next server will be selected in the server list based on the server Load balancer algorithm (such as round-robin) for further processing.
Active Health Check)
As mentioned above, Nginx has two major functions: one is expansion, adding more servers to meet greater concurrency, and the other is to detect invalid servers for timely elimination. Therefore, it is very important to define a "failed server. This section discusses this issue. This is only available in NGINX Plus and is charged.
The open-source NGINX version provides simple health check and automatic failover. But how to define an upstream server "invalid" Open Source NGINX is simple. NGINX Plus providesCustomizable and comprehensive criteriaIn addition, NGINX Plus can also Gently add new server nodes to the cluster. This feature allows NGINX Plus to identify more diversified server errors, effectively increasing the reliability of HTTP, TCP, and UDP applications.
The following commands are used: health_check and match:
Upstream my_upstream {zone my_upstream 64 k; server server1.example.com slow_start = 30 s;} server {#... location/health {internal; health_check interval = 5S uri =/test. php match = statusok; proxy_set_header HOST www.example.com; proxy_pass http: // my_upstream} match statusok {# In/test. php performs health check status 200; header Content-Type = text/html; body ~ "Server [0-9] + is alive ";}
In health_check, interval = 5s indicates detection every 5s; uri =/test. php indicates in/test. for health check in php, NGINX Plus automatically initiates a uri request. The uri can be customized. You can execute the check logic in it, for example, whether mysql/redis is normal, then, make a certain response. Then, in the match command, match/test through some rules. php response. The/test. php response can include status, header, and body for matching with the subsequent commands. If all the items pass the check, even if they are healthy, the server is marked as active. If a match fails, such as Content-Type = text/json or status = 201, the check fails, server is unhealthy and marked as inactive.
Use DNS to discover new services
When Nginx Plus is started, it performs DNS resolution and automatically caches the resolved domain name and IP address permanently. However, in some cases, you need to re-resolve the domain name and IP address. In this case, you can use the following command to achieve this:
resolver 127.0.0.11 valid=10s;upstream service1 { zone service1 64k; server www.example.com service=http resolve;}
127.0.0.11 is the default DNS server address. In this example, the DNS server in NGINX Plus initiates a re-resolution request every 10 s.
Access Controls)
NGINX Plus Release 7 mainly improves the security of TCP load balancing. For example, Access Controls and DDoS protection.
You can now allow or deny access to the TCP server that performs reverse proxy or load balancing, simply by configuring a simple IP address or an IP address example:
server { # ... proxy_set_header Host www.example.cn; proxy_pass http://test; deny 72.46.166.10; deny 73.46.156.0/24; allow all;}
The first deny command rejects access from an IP address, and the second command rejects access from an IP address range. All the other two are allowed access. If the access is denied, error 403 is returned.
Connection Limiting)
With NGINX Plus R7, you can limit the number of TCP requests sent from the client to the NGINX Plus proxy to prevent excessive TCP requests. Some of your applications may be slower than the others. For example, a request to a part of your application will produce a large number of MySQL requests, or fork will generate a large number of work processes. Then attackers will use this to generate thousands of requests, causing your server to be overloaded.
However, with the connection limit function, you can configure the limit_conn my_limit_conn command to limit the maximum number of requests that can be initiated by the same client (IP), so as to minimize the above attack risks.
stream { limit_conn_zone $binary_remote_addr zone=my_limit_conn:10m; # ... server { limit_conn my_limit_conn 1; # ... }}
This command limits that each IP Address can have only one connection at the same time.
Bandwidth Limiting)
R7 also adds a feature that limits the maximum bandwidth for uploading and downloading each connection.
server { # ... proxy_download_rate 100k; proxy_upload_rate 50k;}
With this configuration, the client can only download at a maximum of 100 kbytes/s and upload at a speed of 50 kbytes/s. Because the client can open multiple connections, if you want to limit the total upload/download speed, you also have to limit the number of connections to the single client.
Supports unbuffered upload
This is a feature added in R6. You can use unbuffered upload in R6 and later versions, which means Nginx Plus can use larger Http requests, such as upload. Unbuffered uploads can be uploaded as soon as these requests come, rather than buffering all the uploaded content as before, and then forwarding it to your upstream server.
By default, when Nginx is uploaded, it will first buffer the received data into a buffer to avoid binding resources to backend scripts based on the worker process, however, event-driven backend languages such as Node. js, buffering is almost unnecessary. This modification improves the server's responsiveness to uploading large files, because the application can respond immediately as soon as the data is received, making the upload progress bar real-time and accurate. Similarly, this improvement reduces disk I/O.
SSL/TLS Optimization
In R6, you can provide a certificate for the client when dealing with the upstream HTTPS or uwSGI server. This greatly improves security, especially when communicating with security services on unprotected networks. R6 supports SSL/TLS client authentication for IMAP, POP3, and SMTP.
Cache Optimization
The proxy_cache command supports variables. This simple improvement allows you to define several disk-based caches and make free choices based on the request data. It is useful when you plan to create a huge content cache and save it to different disks.
API functions
Some commands of the upstreem module can be modified not only manually, but also through restful api and automatically updated immediately. With this function, you can change some functions of NGINX Plus through APIS. Application has been greatly improved. Of course, this is also charged:
upstream backend { zone backends 64k; server 10.10.10.2:220 max_conns=250; server 10.10.10.4:220 max_conns=150;}server { listen 80; server_name www.example.org; location /api { api write=on; }}
With the API, you can use the curl tool to dynamically modify the configuration. For example, you can use the POST command to add a cluster node:
$ curl -iX POST -d '{"server":"192.168.78.66:80","weight":"200","max_conns":"150"}' http://localhost:80/api/1/http/upstreams/backend/servers/
It is equivalent to adding a configuration like this:
Upstream backend {zone backends 64 k; server 10.10.10.2: 220 max_conns = 250; server 10.10.10.4: 220 max_conns = 150; # Here is the server 192.168.78.66 added through the api: 80 weight = 200 max_conns = 150 ;}
If you need to modify a node configuration, you can use the natural sequence of server nodes in the connection pool (starting from 0) as their unique IDs, and then use the PATCH/DELETE method to operate on them:
$ curl -iX PATCH -d '{"server":"192.168.78.55:80","weight":"500","max_conns":"350"}' http://localhost:80/api/1/http/upstreams/backend/servers/2
This command is used to modify the third server 192.168.78.66: 80 max_conns = 200 in the connection pool:
server 192.168.78.55:80 weight=500 max_conns=350;
To return information about all nodes, you can use:
$ curl -s http://localhost:80/api/1/http/upstreams/backend/servers/
Returns a JSON string.
{ "backup": false, "down": false, "fail_timeout": "10s", "id": 0, "max_conns": 250, "max_fails": 1, "route": "", "server": "10.10.10.2:220", "slow_start": "0s", "weight": 1 }, { "backup": false, "down": false, "fail_timeout": "10s", "id": 1, "max_conns": 150, "max_fails": 1, "route": "", "server": "10.10.10.4:220", "slow_start": "0s", "weight": 1 }, { "backup": false, "down": false, "fail_timeout": "10s", "id": 2, "max_conns": 200, "max_fails": 1, "route": "", "server": "192.168.78.66:80", "slow_start": "0s", "weight": 200 } }
Configuration best practices
Creating directories and files for different application configurations and merging them with the include command is a good habit. The standard NGINX Plus configuration is to put the configuration files of each application under their conf. d directory:
http { include /etc/nginx/conf.d/*.conf;}stream { include /etc/nginx/stream.d/*.conf;}
The http and stream modules belong to different directories. In http, both http request configurations and stream are TCP/UDP request configurations. There are no uniform standards, mainly because developers can easily identify and modify them.