一、反向代理与负载均衡:概念解析
在现代 Web 架构中,反向代理(Reverse Proxy) 是位于客户端与后端服务器之间的中间层,它接收客户端请求并将其转发到适当的后端服务器,然后将服务器的响应返回给客户端。反向代理对客户端是透明的——客户端认为自己在直接与源服务器通信。
负载均衡(Load Balancing) 则是将传入的网络流量分发到多台后端服务器的技术。它解决了单台服务器无法承载高并发流量的瓶颈问题,同时提供了故障转移(Failover)能力。
Nginx 凭借其事件驱动架构和异步非阻塞 I/O 模型,天然适合承担反向代理和负载均衡的角色。在 10,000 并发连接下内存占用仅约 2.5MB,这使其成为业界最广泛采用的方案之一。
二、Nginx 安装与基础配置
Ubuntu/Debian 安装
# 更新包索引
sudo apt update
# 安装 Nginx
sudo apt install nginx -y
# 验证安装
nginx -v
# 输出: nginx version: nginx/1.24.0
# 启动并设置开机自启
sudo systemctl start nginx
sudo systemctl enable nginx
# 检查状态
sudo systemctl status nginx
配置文件结构
/etc/nginx/
├── nginx.conf # 主配置文件
├── sites-available/ # 可用站点配置
│ └── default
├── sites-enabled/ # 已启用站点(符号链接)
│ └── default -> ../sites-available/default
├── conf.d/ # 额外配置片段
├── snippets/ # 可复用配置片段
│ ├── ssl-params.conf
│ └── proxy-params.conf
└── mime.types # MIME 类型映射
三、反向代理核心配置
以下是一个完整的反向代理配置,将请求转发到本地 Node.js 应用(端口 3000):
server {
listen 80;
server_name example.com www.example.com;
# 日志配置
access_log /var/log/nginx/example.access.log;
error_log /var/log/nginx/example.error.log;
# 客户端请求体大小限制(文件上传等)
client_max_body_size 50M;
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;
proxy_set_header X-Forwarded-Proto $scheme;
# 超时配置
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# 缓冲配置
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
}
# 静态资源直接由 Nginx 处理
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf)$ {
root /var/www/example/public;
expires 30d;
add_header Cache-Control "public, immutable";
}
}
四、负载均衡策略详解
Nginx 通过 upstream 模块实现负载均衡,支持多种调度算法:
1. 轮询(Round Robin)—— 默认策略
upstream backend {
server 192.168.1.10:3000;
server 192.168.1.11:3000;
server 192.168.1.12:3000;
}
请求按顺序轮流分配到各服务器。适合各服务器性能相近的场景。
2. 加权轮询(Weighted Round Robin)
upstream backend {
server 192.168.1.10:3000 weight=3; # 处理 3/6 请求
server 192.168.1.11:3000 weight=2; # 处理 2/6 请求
server 192.168.1.12:3000 weight=1; # 处理 1/6 请求
}
3. IP 哈希(IP Hash)
upstream backend {
ip_hash;
server 192.168.1.10:3000;
server 192.168.1.11:3000;
server 192.168.1.12:3000;
}
同一客户端 IP 始终路由到同一台后端服务器,解决 Session 共享问题。
4. 最少连接(Least Connections)
upstream backend {
least_conn;
server 192.168.1.10:3000;
server 192.168.1.11:3000;
server 192.168.1.12:3000;
}
五、健康检查与故障转移
Nginx 提供了被动健康检查和主动健康检查两种机制:
upstream backend {
server 192.168.1.10:3000 max_fails=3 fail_timeout=30s;
server 192.168.1.11:3000 max_fails=3 fail_timeout=30s;
server 192.168.1.12:3000 backup; # 备用服务器
}
参数说明:
max_fails=3:30秒内失败3次标记为不可用fail_timeout=30s:不可用状态持续30秒后重试backup:备用服务器,仅在其他服务器全部不可用时启用down:手动标记服务器为不可用(维护模式)
六、SSL/TLS 终端配置
server {
listen 443 ssl http2;
server_name example.com;
# SSL 证书路径
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# 现代 SSL 配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers on;
# 启用 HSTS
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
location / {
proxy_pass http://backend;
proxy_set_header X-Forwarded-Proto https;
}
}
# HTTP → HTTPS 重定向
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
七、生产环境完整配置模板
upstream app_cluster {
least_conn;
server 127.0.0.1:3001 weight=3 max_fails=2 fail_timeout=20s;
server 127.0.0.1:3002 weight=3 max_fails=2 fail_timeout=20s;
server 127.0.0.1:3003 backup;
keepalive 32; # 长连接池大小
}
server {
listen 443 ssl http2;
server_name api.example.com;
ssl_certificate /etc/ssl/certs/example.pem;
ssl_certificate_key /etc/ssl/private/example.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
client_max_body_size 20M;
client_body_buffer_size 128k;
# Gzip 压缩
gzip on;
gzip_types text/plain application/json application/javascript text/css;
gzip_min_length 256;
location / {
proxy_pass http://app_cluster;
proxy_http_version 1.1;
proxy_set_header Connection "";
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_connect_timeout 10s;
proxy_read_timeout 30s;
proxy_send_timeout 30s;
proxy_buffering on;
proxy_buffer_size 8k;
proxy_buffers 16 8k;
# 限流
limit_req zone=api_limit burst=20 nodelay;
}
location /health {
proxy_pass http://app_cluster;
access_log off;
}
}
# 请求限流区域
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=100r/s;
八、性能调优参数
| 参数 | 推荐值 | 说明 |
|---|---|---|
worker_processes | auto | 自动匹配 CPU 核心数 |
worker_connections | 4096 | 每个 Worker 最大连接数 |
keepalive_timeout | 65 | Keep-Alive 超时时间 |
keepalive_requests | 1000 | 单连接最大请求数 |
sendfile | on | 启用零拷贝文件传输 |
tcp_nopush | on | 优化 TCP 包发送 |
九、常见问题排查
502 Bad Gateway
后端服务未启动或无法连接。排查步骤:
- 确认后端服务是否运行:
netstat -tlnp | grep :3000 - 检查 Nginx 错误日志:
tail -f /var/log/nginx/error.log - 测试直接访问后端:
curl http://127.0.0.1:3000
504 Gateway Timeout
后端响应超时。增大 proxy_read_timeout 值,或检查后端是否存在慢接口。
请求头丢失
确保配置了 proxy_set_header 传递必要的请求头,特别是 Host 和 X-Forwarded-* 系列头。
💡 最佳实践建议
将重复的 proxy 配置抽取为 snippet 文件,在多个 location 中通过 include 复用,减少配置冗余。同时建议对上游服务器启用 keepalive 长连接,显著降低 TCP 握手开销。