Reverse Proxy Implementation

πŸ”€ 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: #

  1. Load Balancing: Distribute traffic across multiple servers
  2. Security: Hide backend infrastructure and provide WAF capabilities
  3. SSL Termination: Handle HTTPS encryption/decryption
  4. Caching: Improve performance by storing common responses
  5. Compression: Reduce bandwidth usage
  6. Authentication: Centralize access control
  7. 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 80
  • server_name: Domain name for this virtual host
  • location: Route requests based on URL path
  • proxy_pass: Forward requests to backend services
  • proxy_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 #

  1. Install Nginx:

    sudo apt update
    sudo apt install nginx
    
  2. Create Configuration:

    sudo nano /etc/nginx/conf.d/library-app.conf
    # Paste your configuration here
    
  3. Test Configuration:

    sudo nginx -t
    
  4. Apply Configuration:

    sudo systemctl reload nginx
    
  5. 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

πŸ“š Further Learning Resources #