# Nginx as a Reverse Proxy and Load Balancer

Nginx is a high-performance web server that is widely used as a reverse proxy and load balancer for handling traffic to backend application servers. It efficiently manages request routing, distributes load, and improves fault tolerance.

***

### 1. Basic Reverse Proxy Configuration

A **reverse proxy** forwards client requests to backend servers, which helps in load balancing, caching, and security.

#### **Example: Proxying Requests to a Backend Server**

```nginx
server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://backend_app;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

upstream backend_app {
    server 127.0.0.1:5000;
}
```

In this example:

* Requests to `example.com` are forwarded to the backend application at `127.0.0.1:5000`.
* Headers are preserved to ensure correct request information.

***

### 2. Proxying Dynamic Content to Application Servers

Modern applications use various backend technologies. Nginx can proxy requests to Node.js, Python, Java (Spring Boot), PHP, etc.

#### **Example: Proxying Requests to a Node.js Application**

```nginx
server {
    listen 80;
    server_name api.example.com;

    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
    }
}
```

Here, requests are forwarded to a Node.js app running on port `3000`.

#### **Example: Proxying Requests to a Spring Boot Application**

```nginx
server {
    listen 80;
    server_name spring.example.com;

    location /api/ {
        proxy_pass http://localhost:8080/;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
```

This proxies API calls to a Spring Boot backend running on `8080`.

***

### 3. Load Balancing Algorithms

Nginx supports multiple load balancing strategies to distribute traffic across multiple backend servers.

#### **1. Round Robin (Default)**

Requests are evenly distributed among available servers.

```nginx
upstream backend {
    server app1.example.com;
    server app2.example.com;
}
server {
    location / {
        proxy_pass http://backend;
    }
}
```

#### **2. Least Connections**

Traffic is routed to the server with the fewest active connections.

```nginx
upstream backend {
    least_conn;
    server app1.example.com;
    server app2.example.com;
}
```

#### **3. IP Hash (Sticky Sessions)**

Requests from the same client IP always go to the same backend server.

```nginx
upstream backend {
    ip_hash;
    server app1.example.com;
    server app2.example.com;
}
```

***

### 4. Health Checks & Failover Strategies

Nginx can detect failing servers and redirect traffic accordingly.

#### **Example: Setting Up Health Checks**

```nginx
upstream backend {
    server app1.example.com max_fails=3 fail_timeout=30s;
    server app2.example.com;
}
```

* If `app1.example.com` fails 3 times within 30 seconds, it is marked as down.
* Traffic is automatically rerouted to `app2.example.com`.

***

### 5. Handling WebSockets with Nginx

WebSockets require special handling in Nginx to support persistent connections.

#### **Example: Reverse Proxy WebSockets**

```nginx
server {
    listen 80;
    server_name ws.example.com;

    location /ws/ {
        proxy_pass http://websocket_server;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
    }
}
```

* WebSockets use the `Upgrade` header for persistent connections.
* The `proxy_http_version 1.1;` directive ensures WebSocket compatibility.

***

### 6. Handling CORS with Nginx

CORS (Cross-Origin Resource Sharing) must be configured when serving APIs to prevent security issues.

#### **Example: Allowing CORS for APIs**

```nginx
server {
    listen 80;
    server_name api.example.com;

    location / {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';

        if ($request_method = 'OPTIONS') {
            return 204;
        }
    }
}
```

This configuration allows cross-origin requests and preflight `OPTIONS` requests for APIs.

***

### 7. Conclusion

Nginx is a powerful tool for proxying requests, balancing traffic, and optimizing application performance. By using the right configurations, you can:

* Distribute load across multiple servers efficiently.
* Ensure high availability with failover strategies.
* Handle WebSockets and CORS seamlessly.
