π Reverse Proxies in Microservices #
π Forward Proxy vs Reverse Proxy #
Feature | Forward Proxy | Reverse Proxy |
---|---|---|
Position | Between client and internet | Between internet and backend servers |
Client Awareness | Configured in client | Transparent to client |
Used For | Anonymity, content filtering, caching | Load balancing, SSL, routing, caching |
Hides | Client | Server |
Example Tools | Squid, TinyProxy | Nginx, HAProxy, Apache HTTPD |
π What is a Reverse Proxy? #
A reverse proxy sits in front of one or more backend servers, intercepting requests from clients before they reach the servers. Unlike a forward proxy that acts on behalf of clients, a reverse proxy acts on behalf of servers.
Key Characteristics: #
- Transparent to clients: Clients don’t need special configuration
- Server-side deployment: Managed by server/infrastructure administrators
- Centralized control: Provides a single entry point to multiple backend services
- Enhanced security: Shields backend servers from direct exposure
Primary Benefits: #
- Load Balancing: Distribute traffic across multiple servers
- Security: Hide backend infrastructure and provide WAF capabilities
- SSL Termination: Handle HTTPS encryption/decryption
- Caching: Improve performance by storing common responses
- Compression: Reduce bandwidth usage
- Authentication: Centralize access control
- Monitoring: Unified logging and metrics collection
βοΈ Why Use Nginx in Microservices? #
In a microservice architecture, each service runs on a different port or container. Nginx serves as an ideal reverse proxy because it:
- Routes requests to appropriate services based on URL paths
- Centralizes access through a single domain/IP
- Provides caching and compression for improved performance
- Enhances security via rate limiting, SSL, and request filtering
- Offers high performance with low resource consumption
- Supports WebSockets for real-time communication
- Enables blue-green deployments and A/B testing
π Microservices Architecture with Nginx #
INTERNET
|
|
βΌ
+-------------+
| |
| NGINX |
| REVERSE |
| PROXY |
| |
+------+------+
|
+--------------------+--+--+--------------------+
| | | |
βΌ βΌ βΌ βΌ
+----------------+ +----------------+ +----------------+ +----------------+
| | | | | | | |
| USERS SERVICE | | BOOKS SERVICE | | LOANS SERVICE | | STATIC CONTENT |
| :5001 | | :5002 | | :5003 | | |
| | | | | | | |
+-------+--------+ +-------+--------+ +-------+--------+ +----------------+
| | |
βΌ βΌ βΌ
+----------------+ +----------------+ +----------------+
| | | | | |
| USERS DB | | BOOKS DB | | LOANS DB |
| | | | | |
+----------------+ +----------------+ +----------------+
π¦ Example Nginx Configuration #
Let’s implement a reverse proxy for a microservice architecture with three services:
- Users API at
http://localhost:5001
- Books API at
http://localhost:5002
- Loans API at
http://localhost:5003
Basic Configuration: #
# /etc/nginx/nginx.conf or /etc/nginx/conf.d/default.conf
server {
listen 80;
server_name library-app.example.com;
# Access logging
access_log /var/log/nginx/library-app.access.log;
error_log /var/log/nginx/library-app.error.log;
# Users Service
location /api/users/ {
proxy_pass http://localhost:5001/;
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_set_header X-Forwarded-Proto $scheme;
}
# Books Service
location /api/books/ {
proxy_pass http://localhost:5002/;
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_set_header X-Forwarded-Proto $scheme;
}
# Loans Service
location /api/loans/ {
proxy_pass http://localhost:5003/;
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_set_header X-Forwarded-Proto $scheme;
}
# Static content
location / {
root /var/www/html;
try_files $uri $uri/ /index.html;
}
}
Understanding the Configuration: #
listen 80
: Accept HTTP connections on port 80server_name
: Domain name for this virtual hostlocation
: Route requests based on URL pathproxy_pass
: Forward requests to backend servicesproxy_set_header
: Pass important headers to backends
πΌοΈ Architecture Diagram #
ββββββββββββββ
β Client β
ββββββ¬ββββββββ
β
βΌ
βββββββββββββββ
β NGINX β
β ReverseProxyβ
ββββββ¬βββββββββ
ββββββββββββββΌβββββββββββββ
βΌ βΌ βΌ
ββββββββββββββ ββββββββββββββ ββββββββββββββ
β Users API β β Books API β β Loans API β
β :5001 β β :5002 β β :5003 β
ββββββββββββββ ββββββββββββββ ββββββββββββββ
π Advanced Nginx Capabilities #
β SSL Termination #
Let Nginx handle HTTPS so backend services don’t have to:
server {
listen 443 ssl;
server_name library-app.example.com;
ssl_certificate /etc/ssl/certs/library-app.crt;
ssl_certificate_key /etc/ssl/private/library-app.key;
# Modern SSL configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
# HSTS (optional)
add_header Strict-Transport-Security "max-age=63072000" always;
location /api/ {
proxy_pass http://localhost:5000/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
β Load Balancing #
Distribute traffic across multiple instances of the same service:
# Define upstream server groups
upstream users_service {
server 10.0.0.1:5001 weight=3;
server 10.0.0.2:5001 weight=1;
server 10.0.0.3:5001 backup;
}
server {
location /api/users/ {
proxy_pass http://users_service/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
β Rate Limiting #
Control excessive requests to sensitive routes:
# Define rate limiting zone
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
server {
# Apply rate limiting to specific endpoints
location /api/loans/checkout {
limit_req zone=api_limit burst=20 nodelay;
proxy_pass http://localhost:5003/checkout;
}
}
β Caching #
Improve performance for static or repeated content:
# Define cache location and settings
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=api_cache:10m max_size=1g inactive=60m;
server {
# Apply caching to book catalog (read-heavy, change-infrequent)
location /api/books/catalog {
proxy_cache api_cache;
proxy_cache_valid 200 10m;
proxy_cache_key $scheme$host$request_uri;
proxy_pass http://localhost:5002/catalog;
# Add cache status header
add_header X-Cache-Status $upstream_cache_status;
}
}
π» Practical Implementation Steps #
-
Install Nginx:
sudo apt update sudo apt install nginx
-
Create Configuration:
sudo nano /etc/nginx/conf.d/library-app.conf # Paste your configuration here
-
Test Configuration:
sudo nginx -t
-
Apply Configuration:
sudo systemctl reload nginx
-
Monitor Logs:
sudo tail -f /var/log/nginx/error.log
π οΈ Troubleshooting Common Issues #
Symptom | Possible Cause | Fix |
---|---|---|
502 Bad Gateway | Backend service not running | Ensure backend is running and port is correct |
504 Gateway Timeout | Backend service too slow to respond | Increase proxy_read_timeout value |
Missing Client IP | Headers not forwarded properly | Add proper proxy_set_header directives |
Incorrect Routing | Path mismatch in proxy_pass | Check path handling in location blocks |
SSL Certificate Issues | Certificate misconfiguration | Verify certificate paths and permissions |
Caching Not Working | Cache configuration incorrect | Check cache keys and paths |
Debugging Commands: #
# Check if Nginx is running
systemctl status nginx
# Test configuration syntax
nginx -t
# Check open ports
netstat -tulpn | grep nginx
# Test backend connectivity
curl -v http://localhost:5001/
# Check logs
tail -f /var/log/nginx/error.log
π§ Key Concepts to Remember #
- Reverse proxies are server-side intermediaries that clients connect to directly
- They hide backend infrastructure from clients
- They provide centralized control for distributed services
- Nginx excels as a reverse proxy due to its performance and flexibility
- Key capabilities include routing, load balancing, SSL termination, and caching
- Proper header forwarding is essential for microservices to function correctly