When you need load balancing
When a single DMIT instance can no longer handle traffic, or the business cannot tolerate a single point of failure, requests must be distributed across multiple servers. Load balancing splits into Layer 4 (TCP/UDP — fast forwarding) and Layer 7 (HTTP/HTTPS — route by path/cookie and offload TLS). This guide builds a Layer 7 setup on DMIT using Nginx.
Architecture overview
visitors → LB (Nginx, DMIT instance A)
├→ app1 (DMIT instance B)
├→ app2 (DMIT instance C)
└→ app3 (DMIT instance D)
The LB-to-backend link can be private or public. For cross-region deployments, combine with location selection to place backends in different regions for failover.
Nginx upstream config
# /etc/nginx/conf.d/lb.conf
upstream myapp {
least_conn; # least-connections scheduling
server 10.0.0.11:8000 weight=2 max_fails=3 fail_timeout=30s;
server 10.0.0.12:8000 max_fails=3 fail_timeout=30s;
server 10.0.0.13:8000 backup; # standby node
keepalive 32;
}
server {
listen 443 ssl;
server_name example.com;
# ssl_certificate ...;
location / {
proxy_pass http://myapp;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_next_upstream error timeout http_502; # automatic failover
}
}
Choosing a scheduling policy
| Policy | Behaviour | Fits |
|---|---|---|
| round-robin | Rotate evenly (default) | Similar backend capacity |
| least_conn | Pick the node with fewest active connections | Highly variable request durations |
| ip_hash | Pin one IP to one node | Simple session stickiness without shared state |
| weight | Distribute by weight | Uneven backend specs |
Health checks
Open-source Nginx uses passive checks: max_fails + fail_timeout temporarily remove a node after repeated failures. For active probing, add a lightweight health endpoint plus a cron job:
# backend serves /healthz returning 200
# probe every minute from the LB and alert
*/1 * * * * curl -sf http://10.0.0.11:8000/healthz || echo "app1 down" | mail -s "LB alert" ops@example.com
Full monitoring/alerting in Prometheus + Grafana Monitoring.
Sessions and shared state
- Prefer externalising state: sessions in Redis, files in object storage — any node can serve any request
- If state cannot move, use
ip_hashor app-level sticky cookies as a stopgap - Keep databases single-writer; read scaling in Database Optimisation
TLS offload and end-to-end HTTPS
- Certificates only on the LB, HTTP to private backends — simple config, centralised renewal (see HTTPS Setup)
- Encrypt links crossing the public internet: backends get certs too, LB uses
proxy_pass https://with verification - Pass
X-Forwarded-Protoso apps know the original scheme and avoid redirect loops
Common issues
Bursts of 502?
Check each backend's health and the LB error log (tail -f /var/log/nginx/error.log); usually a dead backend process or missing HTTP/1.1 keepalive settings. See Troubleshooting Guide.
Users losing login state?
Sessions are not shared across nodes. Move sessions to Redis, or switch to ip_hash temporarily.
Real visitor IP missing?
Ensure the LB sets X-Real-IP/X-Forwarded-For and the app trusts those headers; with a CDN in front, also see CDN Setup.
Related articles
Prometheus + Grafana Monitoring, Performance Tuning, CI/CD Deploy.
Data checked: 2026-08-18. Nginx directives follow official documentation.