Nginx 反向代理:从原理到生产实践 —— 以 What-to-eat-today 项目为例
Nginx反向代理DevOpsDocker架构设计
Nginx 反向代理:从原理到生产实践 —— 以 What-to-eat-today 项目为例
深入理解 Nginx 反向代理的核心原理、配置技巧与生产最佳实践,结合 Datawhale all-in-rag 实战项目进行工程化应用分析。
目录
一、为什么需要学习 Nginx 反向代理?
核心原因
| 原因 | 说明 | 生产影响 |
|---|---|---|
| 前后端分离架构的必然要求 | 前端 SPA + 后端 API 需要统一入口 | 不配置反向代理就会存在 CORS 跨域问题 |
| 微服务网关的基石 | 多个微服务通过 Nginx 路由分发 | 单点入口才能做统一的鉴权、限流、日志 |
| SSL/TLS 统一终结 | 证书只需配置在 Nginx 一层 | 后端服务无需处理 HTTPS,降低复杂度 |
| 静态资源高性能托管 | Nginx 处理静态文件比 Python/Java 快 10x+ | 直接提升首屏加载性能 |
直观理解
反向代理就是”前台接待员”:访客(客户端)不需要知道公司内部谁在做什么(后端服务),只需对接待员说出需求,接待员在内部找到对应的人并转达结果。
相比之下,正向代理(VPN)是”你替我去拿”——你告诉代理服务器你要访问某个网站,代理帮你去取回来。
二、反向代理核心原理
2.1 架构模型对比
| 模式 | 示意图 | 特点 |
|---|---|---|
| 直连模式 | 客户端 → 后端服务 | 暴露后端端口、CORS 问题、无法统一鉴权 |
| 反向代理模式 | 客户端 → Nginx(:80) → 后端服务(:3000/:8000) | 隐藏后端、统一入口、可扩展 |
2.2 Nginx 反向代理的工作流程
客户端请求 example.com/api/users
│
▼
DNS 解析 → 指向 Nginx 服务器 IP(:80)
│
▼
Nginx 接收请求,解析 Host 头部
│
├── location /api/ → proxy_pass http://backend:8000
├── location / → proxy_pass http://frontend:3000
│
▼
后端服务处理请求 → 返回响应 → Nginx 转发回客户端
关键配置指令拆解:
server {
listen 80; # 监听 80 端口(HTTP)
server_name example.com; # 匹配的域名
location /api/ {
proxy_pass http://backend:8000; # 转发到后端 API
proxy_set_header Host $host; # 传递原始 Host
proxy_set_header X-Real-IP $remote_addr; # 传递客户端真实 IP
}
location / {
proxy_pass http://frontend:3000; # 转发到前端 SPA
}
}
2.3 为什么 Nginx 速度这么快?
| 特性 | 说明 | 优势 |
|---|---|---|
| 事件驱动架构 | 非阻塞 I/O,单进程处理万级并发 | 对比 Apache 的进程/线程模型,内存占用低 10x |
| 零拷贝 | 静态文件直接从内核缓存发送到网卡 | CPU 几乎不参与大文件传输 |
| 异步非阻塞 | 一个 worker 进程可同时处理数千连接 | 无需为每个连接创建线程 |
三、实战项目配置:What-to-eat-today
3.1 项目架构
What-to-eat-today
├── frontend/ # React 前端
│ ├── src/
│ └── Dockerfile
├── backend/ # FastAPI 后端
│ ├── app/
│ └── Dockerfile
├── nginx/ # Nginx 配置
│ └── nginx.conf
└── docker-compose.yml # 编排文件
3.2 Nginx 配置
# nginx/nginx.conf
events {
worker_connections 1024;
}
http {
upstream backend {
server backend:8000;
}
upstream frontend {
server frontend:3000;
}
server {
listen 80;
server_name localhost;
# 前端静态资源
location / {
proxy_pass http://frontend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# 后端 API
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;
proxy_set_header X-Forwarded-Proto $scheme;
}
# WebSocket 支持
location /ws/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
}
3.3 Docker Compose 编排
# docker-compose.yml
version: '3.8'
services:
frontend:
build: ./frontend
ports:
- "3000:3000"
backend:
build: ./backend
ports:
- "8000:8000"
nginx:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
depends_on:
- frontend
- backend
四、生产最佳实践
4.1 SSL/TLS 配置
server {
listen 443 ssl;
server_name your-domain.com;
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
# SSL 优化
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
# HSTS
add_header Strict-Transport-Security "max-age=63072000" always;
}
# HTTP 重定向到 HTTPS
server {
listen 80;
server_name your-domain.com;
return 301 https://$server_name$request_uri;
}
4.2 性能优化
http {
# 开启 Gzip 压缩
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
# 静态资源缓存
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# 连接优化
keepalive_timeout 65;
keepalive_requests 100;
}
4.3 安全配置
http {
# 隐藏版本号
server_tokens off;
# 防止点击劫持
add_header X-Frame-Options "SAMEORIGIN" always;
# 防止 MIME 类型嗅探
add_header X-Content-Type-Options "nosniff" always;
# XSS 防护
add_header X-XSS-Protection "1; mode=block" always;
# 限制请求大小
client_max_body_size 10M;
}
结语
Nginx 反向代理是每个开发者都应该掌握的技能。它是前后端分离架构的必备技能,也是微服务网关的基石。基本配置很简单,10 行配置就能解决 CORS 问题。建议读者在实践中多尝试不同的配置,找到最适合自己项目的方案。
关键要点:每个开发者都应该掌握 Nginx 反向代理。基本配置很简单,10 行配置就能解决 CORS 问题。