背景

作为Web服务领域的"瑞士军刀",Nginx的Proxy模块堪称现代互联网架构的交通指挥员。它不仅能让你的服务部署更灵活,还能实现负载均衡、请求优化等高级功能。本文将以Node.js技术栈为例,手把手教你玩转这个强大的工具。


一、反向代理的前世今生

想象一下你开了一家网红奶茶店(后端服务),每天顾客(客户端)挤破门要买奶茶。这时候你在店门口安排了个专业导购(Nginx),负责引导顾客到不同制作台(服务器),还能帮顾客拿吸管和纸巾(请求处理),这就是反向代理的日常。

典型应用场景

  1. 单域名多服务部署(前后端分离架构)
  2. 灰度发布和A/B测试
  3. 负载均衡与故障转移
  4. 静态资源缓存加速
  5. SSL终止和请求过滤

二、基础配置实战

我们先从最简单的单服务代理开始。假设你有两个Node.js服务:

  • 用户服务运行在3000端口
  • 商品服务运行在3001端口
server {
    listen 80;
    server_name myapp.com;

    # 用户服务路由
    location /users {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    # 商品服务路由
    location /products {
        proxy_pass http://localhost:3001;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    # 静态文件服务
    location /static {
        alias /var/www/static_files;
        expires 7d;
    }
}

配置解析

  • proxy_pass:指定实际服务地址
  • proxy_set_header:传递原始请求信息
  • alias+expires:静态文件缓存策略

三、进阶玩法:负载均衡

当你的奶茶店开成连锁品牌时,就需要多个制作台同时工作。Nginx支持多种负载策略:

# 定义上游服务器组
upstream node_cluster {
    server 127.0.0.1:3000 weight=3;  # 权重分配
    server 127.0.0.1:3001;
    server 127.0.0.1:3002 backup;   # 备用服务器
}

server {
    listen 80;
    
    location / {
        proxy_pass http://node_cluster;
        proxy_next_upstream error timeout http_500; # 故障转移条件
        proxy_connect_timeout 2s;    # 连接超时
        proxy_read_timeout 5s;       # 读取超时
    }
}

策略说明

  • 权重分配(weight):3:1的请求分配比例
  • 备用服务器(backup):主服务器不可用时自动启用
  • 健康检查:通过超时设置和状态码判断实现

四、WebSocket代理配置

现在要给奶茶店增加在线点单功能(WebSocket服务),配置需要特别注意:

location /chat {
    proxy_pass http://websocket_server;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_read_timeout 86400s;  # 保持长连接
}

关键参数

  • 强制使用HTTP 1.1协议
  • 升级协议头处理
  • 超时时间调整为24小时

五、SSL终止实践

让导购员统一处理安全证书,减轻奶茶店的负担:

server {
    listen 443 ssl;
    server_name secure.myapp.com;

    ssl_certificate /etc/ssl/certs/myapp.crt;
    ssl_certificate_key /etc/ssl/private/myapp.key;

    location / {
        proxy_pass http://backend_server;
        proxy_set_header X-Forwarded-Proto $scheme; # 传递原始协议
    }
}

安全建议

  1. 使用2048位以上RSA证书
  2. 配置HSTS头部
  3. 启用OCSP Stapling

六、那些年我踩过的坑

  1. 请求头丢失之谜
# 错误示例:未传递必要头部
location /api {
    proxy_pass http://backend;
}

# 正确姿势
location /api {
    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;
}
  1. 缓存引发的血案
# 禁用不需要的缓存
location /dynamic {
    proxy_pass http://backend;
    proxy_cache off;          # 明确关闭缓存
    proxy_no_cache $http_pragma $http_authorization;
}
  1. 大文件上传超时
location /upload {
    proxy_pass http://backend;
    client_max_body_size 1024M;  # 允许上传大文件
    proxy_request_buffering off; # 禁用缓冲
    proxy_send_timeout 300s;     # 上传超时时间
}

七、性能调优秘籍

  1. 连接池优化
http {
    proxy_buffers 16 32k;       # 缓冲区数量和大小
    proxy_buffer_size 64k;      # 响应头缓冲区
    proxy_busy_buffers_size 128k;
    keepalive 32;               # 保持连接数
}
  1. 压缩传输优化
gzip on;
gzip_types text/plain application/json;
gunzip on;  # 支持解压缩上游内容

八、技术选型分析

优势对比

  • vs Apache:更高并发处理能力
  • vs HAProxy:更灵活的配置语法
  • vs Traefik:更成熟的生态体系

局限须知

  1. 四层代理能力较弱(建议结合LVS)
  2. 动态配置需要reload
  3. 缺少图形化监控界面

九、未来演进方向

  1. 云原生架构下的Ingress Controller
  2. 与Service Mesh的集成
  3. QUIC/HTTP3协议支持
  4. 智能化流量调度