1. 为什么需要Nginx反向代理前后端分离项目
现代Web开发中,前后端分离架构已成为主流模式。React作为前端框架的标杆,Python(Django/Flask等)作为后端开发的利器,二者组合能发挥各自优势。但随之而来的部署问题却让不少开发者头疼——如何让前端静态资源与后端API服务完美协作?
我在实际项目部署中遇到过典型问题:React应用运行在3000端口,Python服务监听5000端口。浏览器直接访问React时,所有API请求都会因跨域问题被拦截。虽然可以通过CORS临时解决,但生产环境需要更专业的方案。
Nginx反向代理的价值在于:
- 统一入口:所有流量通过80/443端口进出
- 路径分发:根据URL特征智能路由到前端或后端
- 负载均衡:后端多实例时自动分配流量
- 安全加固:隐藏真实服务端口,过滤恶意请求
- 性能优化:静态文件缓存、Gzip压缩等特性开箱即用
关键提示:开发环境可以用webpack代理或CORS绕过跨域限制,但生产环境必须使用Nginx这类专业方案。我曾因直接暴露后端端口导致服务器被爬虫拖垮,教训深刻。
2. 基础环境准备与安装指南
2.1 系统环境要求
推荐使用Linux服务器(Ubuntu 20.04+或CentOS 7+),我的测试环境配置如下:
- 阿里云ECS
- 2核4G内存
- 50GB SSD云盘
- 公网IP绑定
2.2 组件安装步骤
bash复制# 更新系统包
sudo apt update && sudo apt upgrade -y
# 安装Nginx(最新稳定版)
sudo apt install nginx -y
# 安装Node.js(React依赖)
curl -fsSL https://deb.nodesource.com/setup_16.x | sudo -E bash -
sudo apt install -y nodejs
# 安装Python环境
sudo apt install python3-pip python3-venv -y
验证安装:
bash复制nginx -v # 应显示1.18+
node -v # 应显示v16+
python3 --version # 应显示3.6+
2.3 项目文件结构规划
建议采用以下目录结构,这是我经过多个项目验证的高效方案:
code复制/var/www/
├── frontend/ # React项目
│ ├── build/ # 编译后的静态文件
│ └── ... # 源码目录
├── backend/ # Python项目
│ ├── venv/ # 虚拟环境
│ └── app.py # Flask/Django入口文件
└── logs/ # 统一日志目录
3. React前端部署实战
3.1 生产环境构建优化
在React项目根目录执行:
bash复制npm run build
关键构建参数建议(在package.json中配置):
json复制"build": "GENERATE_SOURCEMAP=false INLINE_RUNTIME_CHUNK=false react-scripts build"
这样生成的build目录:
- 移除了sourcemap(安全考虑)
- 分离runtime代码(提升缓存效率)
- 静态资源自动hash命名(解决缓存更新问题)
3.2 Nginx静态文件配置
编辑/etc/nginx/sites-available/your_domain:
nginx复制server {
listen 80;
server_name yourdomain.com;
location / {
root /var/www/frontend/build;
index index.html;
try_files $uri $uri/ /index.html;
}
}
重点说明:
try_files确保React路由能正常跳转- 建议添加expires头缓存静态资源:
nginx复制location /static { expires 1y; add_header Cache-Control "public"; }
4. Python后端服务配置
4.1 WSGI服务选择
根据Python框架不同选择适配方案:
| 框架 | 推荐WSGI服务器 | 启动命令示例 |
|---|---|---|
| Flask | Gunicorn | gunicorn -w 4 -b :5000 app:app |
| Django | Gunicorn | gunicorn project.wsgi:application |
| FastAPI | Uvicorn | uvicorn main:app --port 5000 |
4.2 进程守护方案
使用systemd管理服务(以Flask为例):
bash复制# /etc/systemd/system/flask.service
[Unit]
Description=Flask Backend Service
After=network.target
[Service]
User=www-data
WorkingDirectory=/var/www/backend
Environment="PATH=/var/www/backend/venv/bin"
ExecStart=/var/www/backend/venv/bin/gunicorn -w 4 -b 127.0.0.1:5000 app:app
[Install]
WantedBy=multi-user.target
启动并验证:
bash复制sudo systemctl daemon-reload
sudo systemctl start flask
sudo systemctl status flask # 应显示active (running)
5. Nginx反向代理核心配置
5.1 完整配置示例
nginx复制server {
listen 80;
server_name api.yourdomain.com;
location / {
proxy_pass http://127.0.0.1:5000;
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_connect_timeout 60s;
proxy_read_timeout 300s;
}
}
5.2 关键参数解析
| 参数 | 推荐值 | 作用说明 |
|---|---|---|
| proxy_connect_timeout | 60s | 后端连接超时时间 |
| proxy_read_timeout | 300s | 等待后端响应时间 |
| proxy_buffer_size | 4k | 代理缓冲区大小 |
| client_max_body_size | 20M | 允许上传文件最大值 |
| keepalive_timeout | 75s | 客户端连接保持时间 |
5.3 动静分离优化方案
更专业的配置方案是将API和静态资源分离:
nginx复制server {
listen 80;
server_name yourdomain.com;
# 前端静态资源
location / {
root /var/www/frontend/build;
try_files $uri $uri/ /index.html;
}
# 后端API接口
location /api/ {
proxy_pass http://127.0.0.1:5000/;
# 其他proxy参数...
}
# 静态文件缓存
location /assets/ {
alias /var/www/frontend/build/static/;
expires 1y;
access_log off;
}
}
6. HTTPS安全加固方案
6.1 Let's Encrypt证书申请
bash复制sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d yourdomain.com -d api.yourdomain.com
自动续期测试:
bash复制sudo certbot renew --dry-run
6.2 安全头部配置
在Nginx配置中添加:
nginx复制add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
add_header Referrer-Policy "strict-origin-when-cross-origin";
add_header Content-Security-Policy "default-src 'self'";
6.3 SSL优化参数
nginx复制ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256...';
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_stapling on;
ssl_stapling_verify on;
7. 性能调优实战技巧
7.1 静态资源缓存策略
nginx复制location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 365d;
add_header Cache-Control "public, immutable";
access_log off;
}
7.2 Gzip压缩配置
nginx复制gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml application/json application/javascript application/xml+rss application/atom+xml image/svg+xml;
7.3 连接数优化
nginx复制events {
worker_connections 1024;
multi_accept on;
use epoll;
}
http {
keepalive_requests 1000;
keepalive_timeout 30s;
}
8. 常见问题排查指南
8.1 502 Bad Gateway错误
排查步骤:
- 检查后端服务是否运行:
bash复制sudo systemctl status flask - 检查端口监听:
bash复制
netstat -tulnp | grep 5000 - 查看Nginx错误日志:
bash复制tail -f /var/log/nginx/error.log
8.2 静态资源404问题
可能原因:
- 文件路径配置错误
- 文件权限不足(确保nginx用户有读取权限)
- SPA路由未正确配置try_files
解决方案:
bash复制sudo chown -R www-data:www-data /var/www/frontend/build
sudo chmod -R 755 /var/www
8.3 跨域问题再现
即使使用Nginx代理,也可能遇到:
- 前端仍发送OPTIONS预检请求
- 后端未正确处理代理头
解决方案:
Flask示例:
python复制from flask_cors import CORS
CORS(app, resources={r"/api/*": {"origins": "https://yourdomain.com"}})
Nginx补充配置:
nginx复制location /api/ {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' 'https://yourdomain.com';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With...';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
}
9. 高级部署方案拓展
9.1 多节点负载均衡
nginx复制upstream backend_servers {
server 127.0.0.1:5000 weight=3;
server 192.168.1.100:5000;
server 192.168.1.101:5000 backup;
}
server {
location /api/ {
proxy_pass http://backend_servers;
# 其他配置...
}
}
9.2 灰度发布方案
通过Nginx的split_clients实现AB测试:
nginx复制split_clients "${remote_addr}AAA" $variant {
50% "production";
50% "canary";
}
server {
location / {
if ($variant = "canary") {
proxy_pass http://canary_server;
}
# 正常路由...
}
}
9.3 Docker集成方案
docker-compose.yml示例:
yaml复制version: '3'
services:
frontend:
build: ./frontend
ports:
- "3000:3000"
volumes:
- ./frontend:/app
backend:
build: ./backend
ports:
- "5000:5000"
environment:
- FLASK_ENV=production
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./certs:/etc/nginx/certs
depends_on:
- frontend
- backend
经过多个项目的实战验证,这套Nginx反向代理方案能稳定支持日均百万PV的流量。关键在于根据业务特点灵活调整参数,并建立完善的监控体系。建议部署后使用Prometheus+Granfa监控Nginx的499、502等错误码频率,及时发现潜在问题。
