Nginx 反向代理深度解析与场景实践指南

147 阅读2分钟

Nginx 反向代理深度解析与场景实践指南

一、反向代理核心概念

1.1 工作原理图解

| 流程节点 | 说明 |
|---------|------|
| Client(浏览器/APP) | 发起请求 |
| Nginx(反向代理服务器) | 接收请求并代理转发 |
| Backend(Node.js/Tomcat) | 处理请求并返回响应 |

请求链路:  
Client(浏览器/APP)→ 发送请求 → Nginx(反向代理服务器)→ 代理转发 → Backend(Node.js/Tomcat)  
响应链路:  
Backend(Node.js/Tomcat)→ 返回响应 → Nginx(反向代理服务器)→ 返回响应 → Client(浏览器/APP)

1.2 关键优势特性

  • IP隐藏:保护后端服务器真实地址
  • 负载均衡:多实例流量分发
  • SSL终结:集中管理HTTPS证书
  • 请求过滤:WAF级安全防护
  • 缓存加速:静态资源优化

二、核心配置指令精解

2.1 proxy_pass

location /api/ {
    # 基础形态(带URI)
    proxy_pass http://backend_server/app_context/;
    
    # 高级形态(变量拼接)
    proxy_pass http://$upstream$request_uri;
    
    # 协议升级
    proxy_pass https://secure_backend;
}

路径匹配规则表

原始路径proxy_pass 目标最终请求路径
/api/http://backend//api/
/api/http://backend/new_context//new_context/
/user/1http://backend/v2//v2/user/1

2.2 proxy_set_header

proxy_set_header Header-Name "HeaderValue";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

标准头配置模板

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-Port  $server_port;

三、典型场景配置方案

3.1 Node.js 应用代理

upstream node_cluster {
    server 127.0.0.1:3000 weight=5;  # 主实例
    server 192.168.1.10:3000 backup; # 热备节点
    keepalive 32;                    # 长连接池
}

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

    ssl_certificate      /etc/ssl/api.example.com.crt;
    ssl_certificate_key  /etc/ssl/api.example.com.key;

    # WebSocket 支持
    location /socket.io/ {
        proxy_pass http://node_cluster;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 86400s;  # 长连接超时
    }

    # REST API 路由
    location /api/v2/ {
        proxy_pass http://node_cluster/v3/;  # 路径重写
        proxy_set_header X-API-Version "2.0";
        proxy_redirect off;
    }
}

3.2 Tomcat Java应用代理

upstream tomcat_servers {
    least_conn;            # 最小连接数策略
    server 10.0.0.2:8080 max_fails=3 fail_timeout=30s;
    server 10.0.0.3:8080;
    server 10.0.0.4:8080 down;  # 维护节点
}

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

    # JSP请求代理
    location ~ \.jsp$ {
        proxy_pass http://tomcat_servers;
        proxy_set_header X-Forwarded-Host $host:$server_port;
        proxy_cookie_path / /;  # 解决路径cookie问题
    }

    # 静态资源直通
    location ~* \.(jpg|css|js)$ {
        root /opt/static;
        expires 30d;
        access_log off;
    }

    # AJP协议支持
    location /java-app/ {
        proxy_pass ajp://tomcat_servers;
        proxy_connect_timeout 5s;
    }
}

四、进阶配置技巧

4.1 多协议支持

# gRPC 代理配置
location /grpc/ {
    grpc_pass grpc://backend_grpc;
    grpc_set_header Authorization $http_authorization;
}

# FastCGI 代理
location /php-app/ {
    fastcgi_pass php_backend;
    include fastcgi_params;
}

4.2 安全增强配置

proxy_hide_header X-Powered-By;  # 隐藏敏感头
proxy_set_header X-Content-Type-Options "nosniff";
proxy_set_header Content-Security-Policy "default-src 'self'";

4.3 性能优化参数

proxy_buffering on;
proxy_buffer_size 8k;
proxy_buffers 256 8k;
proxy_busy_buffers_size 16k;
proxy_temp_path /var/nginx/proxy_temp;

proxy_connect_timeout   75s;
proxy_send_timeout      300s;
proxy_read_timeout      300s;

五、调试与排错指南

5.1 日志诊断配置

log_format proxy_debug '$remote_addr - $remote_user [$time_local] '
                       '"$request" $status $body_bytes_sent '
                       '"$http_referer" "$http_user_agent" '
                       'proxy: $upstream_addr time=$upstream_response_time';

access_log /var/log/nginx/proxy.log proxy_debug;

5.2 常见故障处理表

现象可能原因解决方案
502 Bad Gateway后端服务未启动或连接超时检查后端状态,调整proxy_connect_timeout
404 Not Foundproxy_pass路径配置错误检查location匹配和proxy_pass URI
丢失客户端真实IP未配置X-Forwarded-For头添加proxy_set_header配置
WebSocket连接失败未设置Upgrade头配置HTTP/1.1和Upgrade头
Cookie路径错误未设置proxy_cookie_path添加proxy_cookie_path / /;

六、行业最佳实践

  1. 安全基线配置
# 强制头信息清理
proxy_hide_header Server;
proxy_hide_header X-AspNet-Version;

# 安全头设置
add_header Strict-Transport-Security "max-age=31536000" always;
  1. 灰度发布方案
map $cookie_user_type $backend {
    default      canary_backend;
    "internal"   production_backend;
}

server {
    location / {
        proxy_pass http://$backend;
    }
}
  1. 多CDN源验证
location /verify/ {
    proxy_pass http://cdn_origin;
    proxy_cache_bypass $arg_nocache;
    proxy_ssl_verify on;
    proxy_ssl_name $proxy_host;
}