Build and configure advanced load balancing with NGINX and HAProxy including health checks, SSL termination, and algorithm comparison. This comprehensive guide covers everything from design through implementation, testing, and deployment.
🧪
Theory & Background
Round Robin: send requests to backends in rotation — equal distribution. Ideal for identical backend capacities. Least Connections: send to backend with fewest active connections — better for varying request duration. IP Hash: same client IP always routes to same backend — required for session persistence without shared session store. Weighted Round Robin: backends assigned relative capacities (powerful backend = higher weight). Random: random selection — simple, statistically approximates round robin. HAProxy and NGINX both support all algorithms.
Advertisement
🔨
Components & Requirements
10 components required for this project.
#
Component
Purpose
Qty
1
Ubuntu 22.04 VMs (5 servers)
1 LB + 3 backends + 1 monitor
x5
2
HAProxy 2.8
Layer 4/7 load balancer
x1
3
NGINX 1.24
Reverse proxy and load balancer
x1
4
Keepalived
VRRP for LB high availability
x1
5
Let's Encrypt SSL
HTTPS certificate
x1
6
wrk / ApacheBench
Load testing tool
x1
7
Prometheus + Grafana
Request routing metrics
x1
8
iptables / nftables
Network-level traffic rules
x1
9
Lua (HAProxy scripting)
Custom routing logic
x1
10
GeoIP database
Geographic routing
x1
📋
Step-by-Step Implementation
Follow these 3 steps carefully.
1
Load Balancing Algorithms
Round Robin: send requests to backends in rotation — equal distribution. Ideal for identical backend capacities. Least Connections: send to backend with fewest active connections — better for varying request duration. IP Hash: same client IP always routes to same backend — required for session persistence without shared session store. Weighted Round Robin: backends assigned relative capacities (powerful backend = higher weight). Random: random selection — simple, statistically approximates round robin. HAProxy and NGINX both support all algorithms.
2
NGINX Reverse Proxy with Upstream
NGINX upstream block defines backend pool. Health check (NGINX Plus): actively probe /health every 5s, remove failed backends. Community NGINX: passive health check (remove on consecutive failed requests). SSL termination: client → NGINX (HTTPS) → backends (HTTP). NGINX handles TLS handshake overhead, backends see plain HTTP — reduces backend CPU. Buffer tuning: proxy_buffer_size, proxy_buffers for optimal throughput. Rate limiting: limit_req_zone to prevent per-IP flooding.
3
HAProxy for Advanced Load Balancing
HAProxy: purpose-built high-performance load balancer. Supports TCP (Layer 4) and HTTP (Layer 7) routing. ACL-based routing: if URL starts with /api → backend_api, if /static → backend_cdn, if browser is mobile → backend_mobile. Stick tables: session persistence without IP hash (NGINX cookie-based sticky sessions). HAProxy Stats page: real-time dashboard of backend health, request rates, response times, queue depth. HAProxy achieves 1 million+ requests/second on modern hardware.
💻
Code & Implementation
Core code for haproxy.cfg:
haproxy.cfgConfig
global maxconn 100000 log stdout local0 info stats socket /run/haproxy.sock mode 660 level admin defaults mode http option httplog option dontlognull option forwardfor option http-server-close timeout connect 5s timeout client 30s timeout server 30s frontend catb_https bind *:443 ssl crt /etc/ssl/catb.pem alpn h2,http/1.1 bind *:80 http-request redirect scheme https unless { ssl_fc } # Route based on path acl is_api path_beg /api use_backend api_servers if is_api default_backend web_servers backend web_servers balance roundrobin option httpchk GET /health http-check expect status 200 server web1 192.168.10.11:3000 check inter 2s rise 2 fall 3 server web2 192.168.10.12:3000 check inter 2s rise 2 fall 3 server web3 192.168.10.13:3000 check inter 2s rise 2 fall 3 backend api_servers balance leastconn option httpchk GET /api/health server api1 192.168.10.21:8080 check weight 2 server api2 192.168.10.22:8080 check weight 1 listen stats bind *:8404 stats enable; stats uri /stats; stats refresh 10s; stats auth admin:catb2024
🔬
Testing & Troubleshooting
Test Load Balancer Implementation by verifying each subsystem individually before full integration.
!
Troubleshooting Tips
Verify power voltages, check ground connections, use serial monitor for debug.
🌎
Real-World Applications
*Web application high availability
*Microservices API gateway routing
*Database read replica distribution
*Game server connection distribution
*Content delivery optimization
*A/B testing traffic splitting
*CDN edge server routing
*Burst traffic absorption
🚀
Extensions & Next Steps
Implement global server load balancing with GeoDNS
Add WAF (Web Application Firewall) rules in NGINX
Build automatic backend discovery using Consul
Implement circuit breaker pattern for cascading failure prevention
Add dynamic backend weighting based on response time
🎮
Interactive Playground
Coming Soon
An interactive simulator will be available here — simulate circuits and run code in-browser without hardware.
❓
Frequently Asked Questions
What is the difference between Layer 4 and Layer 7 load balancing?
Layer 4 (Transport) load balancing: routes TCP/UDP connections based on IP and port. Doesn't inspect packet content. Very fast (line-rate possible). Cannot make routing decisions based on HTTP headers, URL, or cookies. Examples: Linux IPVS, AWS NLB. Layer 7 (Application) load balancing: inspects HTTP headers, URL, cookies, and content. Can route /api to API servers, /static to CDN, route based on Accept-Language header, apply authentication, and perform SSL termination. More CPU intensive. Examples: NGINX, HAProxy, AWS ALB. Most web applications need Layer 7.