Web infrastructures hosted in virtual platforms like the Amazon Elastic Compute Cloud (EC2), the Google Cloud Platform, or Microsoft Azure can change rapidly. Self-discovering configurations are becoming necessary, and open source NGINX’s configuration file-based approach is not always flexible and open enough when you automate heavily, when you use autoscaling, or when you deploy updates by rebuilding servers rather than patching existing ones in place.

With NGINX Plus, you can reconfigure load-balanced server groups (both HTTP and TCP/UDP) on the fly using a simple HTTP API or the Domain Name System (DNS).

Using the HTTP API to Reconfigure Load‑Balanced Server Groups

To use the on-the-fly reconfiguration API, you need to include the upstream_conf directive in its own location block (which by convention is called /upstream_conf as in the following snippet). The directive activates a special handler that can be configured to inspect and reconfigure upstream groups in NGINX Plus.

It is important that only authorized users can access the handler. In this example, we restrict access to users on localhost.

location /upstream_conf {
upstream_conf;

allow 127.0.0.1; # permit access from localhost
deny all; # deny access from everywhere else
}

You must also configure a shared memory zone for the upstream servers with the zone directive:

upstream backend {
zone backend 64k;
...
}

An HTTP GET for the upstream group returns a list of the servers in it with the ID numbers used to identify them in change operations:

$ curl http://localhost/upstream_conf?upstream=backend
server 192.168.56.101:80; # id=0
server 192.168.56.102:80; # id=1
server 192.168.56.103:80; # id=2

You can use the upstream_conf handler to add or remove servers, dynamically alter their weights, and set their status as primary, backup, or down. For more details on the other server parameters you can configure, see the reference documentation for upstream server groups.

This capability provides a straightforward way for servers to signal their status to NGINX Plus. For example:

  • When a server in an autoscaled server farm starts up, it can add itself to a named upstream group. When the server shuts down, it can cleanly remove itself from the group.
  • You can dynamically alter the weight for each server. For example, if a server is about to run a backup or large batch job, it can signal NGINX Plus to reduce the load sent to it; requests pinned to that server by session persistence continue, but new connections are throttled back.

You can also use this feature to help orchestrate simple management operations, such as temporarily draining sessions from a running server before taking it offline (for a hardware or software update, for example):

$ curl http://localhost/upstream_conf?upstream=backend\&id=1\&drain=1
server 192.168.56.102:80; # id=1 draining

$ curl http://localhost/upstream_conf?upstream=backend
server 192.168.56.101:80; # id=0
server 192.168.56.102:80; # id=1 draining
server 192.168.56.103:80; # id=2

In NGINX Plus Release 7 and earlier, changes made with the upstream_conf interface do not persist across NGINX Plus restarts or configuration reloads, so they must be regarded as transient and reapplied.

In NGINX Plus Release 8 and later, changes made with the API can be made persistent by including the state directive in the upstream block:

upstream backend {
zone backend 64k;
state /var/lib/nginx/state/backend.state;
}

The state directive names the file in which NGINX Plus stores state information for the servers in the upstream group. When it is included in the configuration, servers cannot be statically defined using the server directive.

The user nginx must have write permission on the /var/lib/nginx/state/ directory. If the directory does not already exist, you can run these commands:

$ sudo mkdir -p /var/lib/nginx/state
$ sudo chown nginx:nginx /var/lib/nginx/state

Using DNS to Reconfigure Load-Balanced Server Groups

Normally, NGINX Plus servers resolve DNS names when they start up, and cache these resolved values persistently. When you use a domain name (like api.u.com in the diagram) to identify a group of upstream servers in the server directive and include the resolve parameter, NGINX Plus periodically re-resolves the name in DNS. If the associated list of IP addresses has changed, NGINX Plus immediately starts load balancing across the updated group of servers. You must also include the resolver directive in the configuration, as shown.

on-the-fly-reconfiguration-with-dns

NGINX Plus Release 9 and later can use the additional information in DNS SRV records, such as the port number. This is configured using the new service=http parameter to the server directive:

http {
resolver 192.168.0.2;

upstream backends {
zone backends 64k;
server api.u.com service=http resolve;
}
}

Using DNS to publish the identities of upstream servers in this way is ideal for organizations that frequently need to change the configuration of upstream server groups, such as those that use autoscaling. The benefit is that DevOps staff can manage the servers in the upstream group without modifying the NGINX Plus configuration directly.