Nginx 反向代理原理与实战配置:从工作机制到生产部署
Nginx 是当今最流行的 Web 服务器之一,凭借超低的内存占用和极高的并发处理能力,广泛用于静态文件服务、反向代理、负载均衡等场景。本文从 Nginx 的工作原理出发,手把手讲解反向代理的配置与生产实践。
一、Nginx 工作原理:Master + Worker 架构
Nginx 采用 多进程 + 异步事件驱动 的架构,这是它高并发的根本原因。
- Master 进程:负责读取配置文件、管理 Worker 进程,本身不处理请求
- Worker 进程:真正处理请求的进程,数量通常等于 CPU 核心数
- 事件模型(epoll):单个 Worker 通过 epoll 同时监听数千个连接,IO 等待时不阻塞,切换到其他连接继续处理
与 Apache 的 prefork(每个连接一个进程)相比,Nginx 的内存占用小得多,10MB 内存可以支撑数万并发连接。
# 验证 Nginx 进程架构 ps aux | grep nginx # nginx: master process /usr/sbin/nginx ← 1 个 Master # nginx: worker process ← N 个 Worker(N = CPU核数)
二、反向代理 vs 正向代理
很多初学者会混淆这两个概念:
- 正向代理:客户端知道代理的存在,通过代理访问目标服务器(如 VPN、科学上网)。代理代表客户端
- 反向代理:客户端不知道代理的存在,直接访问代理服务器,代理再转发到后端(如 Nginx 前的 API 服务)。代理代表服务端
三、反向代理配置详解
# /etc/nginx/sites-available/myapp.conf
server {
listen 80;
server_name api.example.com;
# 反向代理到 Node.js 应用
location / {
proxy_pass http://127.0.0.1:3000;
# 透传客户端真实 IP
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 60s;
# 禁用缓冲(适合 SSE/长轮询场景)
# proxy_buffering off;
}
# 静态文件直接由 Nginx 处理(不走代理)
location /static/ {
alias /var/www/myapp/static/;
expires 30d;
add_header Cache-Control "public";
}
}
重点解释:proxy_set_header X-Real-IP 非常重要,否则后端应用只能看到 Nginx 的 IP,拿不到真实用户 IP。在后端代码里用 request.headers['X-Real-IP'] 获取。
四、负载均衡配置
# 上游服务器组(4种负载均衡策略)
upstream backend {
# 1. 轮询(默认):依次分配
server 192.168.1.10:8080;
server 192.168.1.11:8080;
# 2. 加权轮询:按权重分配
# server 192.168.1.10:8080 weight=3;
# server 192.168.1.11:8080 weight=1;
# 3. ip_hash:同一IP固定到同一台(解决Session问题)
# ip_hash;
# 4. least_conn:最少连接优先(适合长连接)
# least_conn;
# 设置后端长连接(减少 TCP 三次握手)
keepalive 32;
}
server {
location /api/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection ""; # 清空 Connection 头,启用长连接
}
}
五、健康检查与故障摘除
upstream backend {
server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.11:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.12:8080 backup; # 备用服务器,主服务器全挂才启用
}
max_fails=3:30秒内失败3次则摘除该节点;fail_timeout=30s:被摘除后等待30秒再重试。这是原生 Nginx 的被动健康检查,无法主动探测(需要 nginx_upstream_check_module 扩展)。
六、生产环境 HTTPS 配置
server {
listen 443 ssl http2;
server_name api.example.com;
ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
# HSTS:强制客户端使用 HTTPS,一年内不走 HTTP
add_header Strict-Transport-Security "max-age=31536000" always;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto https; # 告诉后端当前是 HTTPS
}
}
# HTTP 强制跳转 HTTPS
server {
listen 80;
server_name api.example.com;
return 301 https://$host$request_uri;
}
七、日常运维命令
nginx -t # 测试配置文件语法,修改后必须先测试 nginx -s reload # 热重载配置(不中断现有连接) nginx -s stop # 立即停止 nginx -s quit # 优雅停止(处理完当前请求再退出) tail -f /var/log/nginx/access.log # 实时查看访问日志 tail -f /var/log/nginx/error.log # 实时查看错误日志
八、常见问题排查
| 错误现象 | 排查方向 |
|---|---|
| 502 Bad Gateway | 后端进程挂掉或端口错误,检查 upstream 配置和后端进程状态 |
| 504 Gateway Timeout | 后端处理超时,检查 proxy_read_timeout 配置 |
| 413 Request Entity Too Large | 上传文件过大,增加 client_max_body_size |
| 拿不到真实IP | 检查 X-Real-IP header 是否配置,以及后端是否正确读取 |
总结
Nginx 反向代理是中小网站最常见的部署架构。理解 Master+Worker 的异步模型有助于做好性能调优;配置 X-Real-IP、健康检查、HTTPS,是生产环境必不可少的步骤。建议把配置文件纳入 Git 版本管理,每次修改后先 nginx -t 验证,再 reload 生效。
