Nginx 反向代理配置

Reverse Proxy Configuration

概述

反向代理是Nginx最重要的功能之一,它允许Nginx作为客户端和后端服务器之间的中介,转发客户端请求到一个或多个后端服务器。本文将详细介绍Nginx反向代理的配置方法、优化技巧和最佳实践。

1. 反向代理基础概念

1.1 正向代理vs反向代理

正向代理:
Client -> Proxy -> Server
客户端知道代理的存在

反向代理:
Client -> Reverse Proxy -> Backend Server(s)
客户端不知道后端服务器的存在

1.2 反向代理的作用

反向代理功能:
├── 负载均衡
├── SSL终端
├── 缓存静态内容
├── 压缩响应
├── 安全防护
├── 请求路由
└── 故障转移

2. 基本反向代理配置

2.1 简单的反向代理

server {
    listen 80;
    server_name example.com;

    location / {
        # 基本反向代理配置
        proxy_pass http://127.0.0.1:8080;

        # 传递客户端信息
        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;
    }
}

2.2 代理到不同的后端服务

server {
    listen 80;
    server_name example.com;

    # 代理到应用服务器
    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    # 代理API请求到API服务器
    location /api/ {
        proxy_pass http://127.0.0.1:8080/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    # 代理静态文件到文件服务器
    location /static/ {
        proxy_pass http://127.0.0.1:9000/;
        proxy_set_header Host $host;

        # 静态文件缓存
        proxy_cache_valid 200 1d;
        expires 1d;
    }
}

2.3 基于子域名的代理

# 主应用
server {
    listen 80;
    server_name example.com www.example.com;

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

# API子域名
server {
    listen 80;
    server_name api.example.com;

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

        # API特定配置
        proxy_read_timeout 300;
        proxy_connect_timeout 300;
        proxy_send_timeout 300;
    }
}

# 管理后台子域名
server {
    listen 80;
    server_name admin.example.com;

    # 访问限制
    allow 192.168.1.0/24;
    allow 10.0.0.0/8;
    deny all;

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

3. 高级代理配置

3.1 代理缓冲区配置

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://backend;

        # 缓冲区配置
        proxy_buffering on;
        proxy_buffer_size 4k;
        proxy_buffers 8 4k;
        proxy_busy_buffers_size 8k;
        proxy_max_temp_file_size 1024m;
        proxy_temp_file_write_size 8k;

        # 请求体缓冲
        client_body_buffer_size 128k;
        client_max_body_size 100m;

        # 头部设置
        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;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Port $server_port;
    }
}

3.2 超时配置

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://backend;

        # 连接超时
        proxy_connect_timeout 60s;

        # 发送超时
        proxy_send_timeout 60s;

        # 读取超时
        proxy_read_timeout 300s;

        # 下一个上游超时
        proxy_next_upstream_timeout 0;
        proxy_next_upstream_tries 0;

        # 头部设置
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    # 长连接API
    location /api/streaming {
        proxy_pass http://streaming-backend;

        # 流式响应配置
        proxy_buffering off;
        proxy_read_timeout 24h;
        proxy_send_timeout 24h;

        # 保持连接
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

3.3 SSL终端代理

server {
    listen 443 ssl http2;
    server_name example.com;

    # SSL证书配置
    ssl_certificate /etc/ssl/certs/example.com.crt;
    ssl_certificate_key /etc/ssl/private/example.com.key;

    # SSL参数
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;

    location / {
        # 代理到HTTP后端
        proxy_pass http://127.0.0.1:8080;

        # SSL相关头部
        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 https;
        proxy_set_header X-Forwarded-Ssl on;

        # 安全头部
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Port 443;
    }
}

# HTTP重定向到HTTPS
server {
    listen 80;
    server_name example.com;
    return 301 https://$server_name$request_uri;
}

4. 上游服务器配置

4.1 定义上游服务器组

http {
    # 基本上游配置
    upstream backend {
        server 127.0.0.1:8080;
        server 127.0.0.1:8081;
        server 127.0.0.1:8082;
    }

    # 带权重的上游配置
    upstream weighted_backend {
        server 127.0.0.1:8080 weight=3;
        server 127.0.0.1:8081 weight=2;
        server 127.0.0.1:8082 weight=1;
    }

    # 带备份服务器的配置
    upstream backend_with_backup {
        server 127.0.0.1:8080;
        server 127.0.0.1:8081;
        server 127.0.0.1:8082 backup;
    }

    server {
        listen 80;
        server_name example.com;

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

4.2 高级上游配置

upstream backend {
    # 负载均衡方法
    least_conn;  # 最少连接数
    # ip_hash;   # IP哈希
    # hash $request_uri;  # 自定义哈希

    # 服务器配置
    server 127.0.0.1:8080 weight=1 max_fails=3 fail_timeout=30s;
    server 127.0.0.1:8081 weight=1 max_fails=3 fail_timeout=30s;
    server 127.0.0.1:8082 weight=1 max_fails=3 fail_timeout=30s backup;

    # 连接保持
    keepalive 32;
    keepalive_requests 100;
    keepalive_timeout 60s;
}

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://backend;

        # 连接保持
        proxy_http_version 1.1;
        proxy_set_header Connection "";

        # 故障转移配置
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
        proxy_next_upstream_tries 3;
        proxy_next_upstream_timeout 10s;

        # 头部设置
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

5. WebSocket代理

5.1 基本WebSocket代理

server {
    listen 80;
    server_name websocket.example.com;

    location / {
        proxy_pass http://127.0.0.1:3000;

        # WebSocket支持
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        # 其他头部
        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_read_timeout 86400;
        proxy_send_timeout 86400;
    }
}

5.2 条件WebSocket代理

server {
    listen 80;
    server_name example.com;

    # 普通HTTP请求
    location / {
        proxy_pass http://http_backend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    # WebSocket请求
    location /ws {
        proxy_pass http://websocket_backend;

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        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_read_timeout 86400;
        proxy_send_timeout 86400;
    }
}

# 在http块中定义连接升级映射
http {
    map $http_upgrade $connection_upgrade {
        default upgrade;
        '' close;
    }
}

6. 动态代理配置

6.1 基于请求头的路由

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

    # 默认后端
    set $backend "http://default_backend";

    # 基于API版本路由
    if ($http_api_version = "v1") {
        set $backend "http://api_v1_backend";
    }

    if ($http_api_version = "v2") {
        set $backend "http://api_v2_backend";
    }

    # 基于用户代理路由
    if ($http_user_agent ~* "mobile") {
        set $backend "http://mobile_backend";
    }

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

6.2 基于地理位置的路由

http {
    # 地理位置映射
    geoip_country /usr/share/GeoIP/GeoIP.dat;

    map $geoip_country_code $backend_pool {
        default http://global_backend;
        US http://us_backend;
        CN http://china_backend;
        EU http://europe_backend;
    }

    server {
        listen 80;
        server_name global.example.com;

        location / {
            proxy_pass $backend_pool;
            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-Country-Code $geoip_country_code;
        }
    }
}

7. 性能优化

7.1 连接池优化

upstream backend {
    server 127.0.0.1:8080;
    server 127.0.0.1:8081;

    # 连接池配置
    keepalive 32;
    keepalive_requests 1000;
    keepalive_timeout 60s;
}

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://backend;

        # HTTP版本和连接复用
        proxy_http_version 1.1;
        proxy_set_header Connection "";

        # 缓冲优化
        proxy_buffering on;
        proxy_buffer_size 8k;
        proxy_buffers 32 8k;
        proxy_busy_buffers_size 16k;

        # 头部设置
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

7.2 缓存配置

http {
    # 代理缓存路径
    proxy_cache_path /var/cache/nginx/proxy 
                     levels=1:2 
                     keys_zone=proxy_cache:10m 
                     max_size=1g 
                     inactive=60m 
                     use_temp_path=off;

    server {
        listen 80;
        server_name example.com;

        location / {
            proxy_pass http://backend;

            # 缓存配置
            proxy_cache proxy_cache;
            proxy_cache_key $scheme$proxy_host$request_uri;
            proxy_cache_valid 200 302 10m;
            proxy_cache_valid 404 1m;

            # 缓存控制
            proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
            proxy_cache_background_update on;
            proxy_cache_lock on;

            # 添加缓存状态头部
            add_header X-Cache-Status $upstream_cache_status;

            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        # 缓存清除接口
        location ~ /purge(/.*) {
            allow 127.0.0.1;
            deny all;
            proxy_cache_purge proxy_cache $scheme$proxy_host$1;
            return 200 "Purged\n";
        }
    }
}

8. 安全配置

8.1 头部安全

server {
    listen 443 ssl http2;
    server_name example.com;

    location / {
        proxy_pass http://backend;

        # 安全头部
        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;

        # 隐藏后端服务器信息
        proxy_hide_header X-Powered-By;
        proxy_hide_header Server;

        # 添加安全头部
        add_header X-Frame-Options SAMEORIGIN always;
        add_header X-Content-Type-Options nosniff always;
        add_header X-XSS-Protection "1; mode=block" always;
        add_header Referrer-Policy "strict-origin-when-cross-origin" always;

        # CSP头部
        add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'" always;
    }
}

8.2 访问控制

server {
    listen 80;
    server_name admin.example.com;

    # IP白名单
    allow 192.168.1.0/24;
    allow 10.0.0.0/8;
    deny all;

    # 基本认证
    auth_basic "Admin Area";
    auth_basic_user_file /etc/nginx/.htpasswd;

    location / {
        proxy_pass http://admin_backend;

        # 传递认证信息
        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-User $remote_user;

        # 请求大小限制
        client_max_body_size 10m;

        # 超时限制
        proxy_read_timeout 30s;
        proxy_send_timeout 30s;
    }
}

9. 监控和调试

9.1 代理状态监控

server {
    listen 8080;
    server_name localhost;

    # 上游状态页面
    location /upstream_status {
        stub_status on;
        access_log off;
        allow 127.0.0.1;
        deny all;
    }

    # 代理状态信息
    location /proxy_status {
        access_log off;
        allow 127.0.0.1;
        deny all;

        return 200 "Proxy Status: OK\nUpstream: backend\nConnections: active\n";
        add_header Content-Type text/plain;
    }
}

9.2 调试配置

server {
    listen 80;
    server_name debug.example.com;

    # 启用调试日志
    error_log /var/log/nginx/debug.log debug;

    location / {
        proxy_pass http://backend;

        # 调试头部
        add_header X-Debug-Backend $upstream_addr;
        add_header X-Debug-Response-Time $upstream_response_time;
        add_header X-Debug-Status $upstream_status;
        add_header X-Debug-Cache $upstream_cache_status;

        # 记录详细的访问日志
        access_log /var/log/nginx/debug_access.log detailed;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

10. 故障排除

10.1 常见问题诊断

# 检查上游服务器状态
curl -I http://127.0.0.1:8080/

# 测试代理连接
curl -H "Host: example.com" http://nginx-server/

# 检查代理头部
curl -v http://example.com/

# 查看代理错误日志
tail -f /var/log/nginx/error.log | grep proxy

# 检查上游连接
netstat -an | grep :8080

10.2 性能测试

# 使用ab进行压力测试
ab -n 1000 -c 10 http://example.com/

# 使用wrk进行测试
wrk -t12 -c400 -d30s http://example.com/

# 监控上游连接
watch 'netstat -an | grep :8080 | wc -l'

小结

通过本文的学习,你应该掌握:

  1. 反向代理的基本概念和配置方法
  2. 上游服务器的配置和管理
  3. WebSocket代理的实现
  4. 动态代理和路由配置
  5. 性能优化和缓存策略
  6. 安全配置和访问控制
  7. 监控调试和故障排除

下一篇文章将介绍Nginx的负载均衡策略。

powered by Gitbook© 2025 编外计划 | 最后修改: 2025-08-29 15:40:15

results matching ""

    No results matching ""