Nginx 反向代理完全指南:从入门到实战
在现代 Web 架构中,反向代理已成为不可或缺的一环。无论是将流量分发到多个后端服务器,还是在后端应用前加一层安全防护,Nginx 凭借其高性能和丰富的功能,成为实现反向代理的首选工具。
本文将深入讲解 Nginx 反向代理的核心概念、配置方法及实战案例,帮助你从零开始搭建高效、可靠的代理服务。
1. 什么是反向代理?
1.1 正向代理 vs 反向代理
- 正向代理:代理客户端,客户端通过代理服务器访问互联网(如翻墙、公司内网)。客户端知道代理的存在。
- 反向代理:代理服务器端,客户端请求到达代理服务器,代理将请求转发给后端真实服务器。客户端不知道后端的存在。
反向代理的典型用途包括:
- 负载均衡
- 安全防护(隐藏后端服务器)
- SSL 终止
- 缓存静态内容
- 统一入口(微服务网关)
1.2 Nginx 作为反向代理的优势
- 高并发处理能力,基于异步非阻塞模型
- 配置灵活,支持多种负载均衡算法
- 内置健康检查、缓存、重试机制
- 易于与 Let’s Encrypt 等工具集成实现 HTTPS
2. 基础反向代理配置
2.1 安装 Nginx
sudo apt updatesudo apt install nginx -y2.2 最简单的反向代理
假设后端应用运行在 http://localhost:3000,我们希望所有访问 http://your-domain.com 的请求都转发给它。
创建配置文件 /etc/nginx/sites-available/app-proxy:
server { listen 80; server_name your-domain.com;
location / { proxy_pass http://localhost: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; }}启用配置:
sudo ln -s /etc/nginx/sites-available/app-proxy /etc/nginx/sites-enabled/sudo nginx -tsudo systemctl reload nginx关键指令说明
proxy_pass:指定后端服务器地址,可以是域名、IP、Unix socket 或 upstream 组名。proxy_set_header:设置转发时携带的头信息,确保后端能获取真实客户端信息。Host:原始请求的主机名X-Real-IP:客户端真实 IPX-Forwarded-For:代理链上的 IP 列表X-Forwarded-Proto:原始协议(http/https)
3. 高级配置
3.1 负载均衡
使用 upstream 块定义一组后端服务器,Nginx 会自动分发请求。
upstream backend { # 默认轮询 server backend1.example.com weight=3; # 权重 3 server backend2.example.com; server 192.168.1.10:8080; server unix:/tmp/backend.sock;
# 备份服务器,其他全部不可用时启用 server backup.example.com backup;}
server { listen 80; server_name api.example.com;
location / { proxy_pass http://backend; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; }}负载均衡算法
| 算法 | 配置 | 说明 |
|---|---|---|
| 轮询(默认) | 无额外参数 | 按顺序轮流分配 |
| 权重轮询 | weight=n | 按比例分配,适合后端性能不均 |
| IP 哈希 | ip_hash; | 根据客户端 IP 哈希分配,保证同一 IP 始终访问同一后端(会话保持) |
| 最少连接 | least_conn; | 优先分配给活动连接数最少的后端 |
| 随机 | random; | 随机选择,可配合 two 选项 |
3.2 WebSocket 代理
WebSocket 连接需要升级协议,必须添加以下配置:
location /ws/ { proxy_pass http://websocket_backend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host;}proxy_http_version 1.1:WebSocket 要求 HTTP/1.1 或更高版本。Upgrade和Connection头告诉后端这是一个 WebSocket 升级请求。
3.3 SSL 终止
将 HTTPS 请求在 Nginx 层解密,然后以 HTTP 转发给后端,减轻后端压力。
server { listen 443 ssl http2; server_name secure.example.com;
ssl_certificate /etc/ssl/certs/example.com.crt; ssl_certificate_key /etc/ssl/private/example.com.key;
location / { 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 https; # 告诉后端原始协议是 https }}
# 强制 HTTP 重定向到 HTTPSserver { listen 80; server_name secure.example.com; return 301 https://$server_name$request_uri;}使用 Let’s Encrypt 自动获取证书:
sudo apt install certbot python3-certbot-nginxsudo certbot --nginx -d secure.example.com3.4 代理缓存
缓存后端响应,减少重复请求,提升性能。
http { # 定义缓存路径和参数 proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=mycache:10m inactive=60m max_size=1g;
server { location / { proxy_cache mycache; proxy_cache_valid 200 302 60m; # 对 200/302 响应缓存 60 分钟 proxy_cache_valid 404 1m; # 404 缓存 1 分钟 proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504; proxy_pass http://backend; } }}proxy_cache_path:缓存目录、等级、内存区域名称、大小、有效期。proxy_cache:引用定义的缓存区域。proxy_cache_valid:不同状态码的缓存时长。proxy_cache_use_stale:当后端出错时,允许使用过期缓存。
3.5 路径重写与传递
通过 location 和 proxy_pass 的配合,可以灵活控制转发路径。
场景:代理到不同路径
# 将 /api/ 下的请求转发到后端 http://backend:8080/v2/location /api/ { proxy_pass http://backend:8080/v2/; # 注意:proxy_pass 结尾带 / 会去除匹配的 /api/ 部分}- 如果
proxy_pass结尾有/,则请求 URI 中匹配的location部分会被替换为proxy_pass的路径。 - 如果结尾没有
/,则整个请求 URI 会拼接到proxy_pass后面。
使用 rewrite 修改 URI
location /legacy/ { rewrite ^/legacy/(.*)$ /new/$1 break; proxy_pass http://backend;}4. 实战案例
4.1 代理 Node.js 应用(Express)
Node.js 应用运行在 3000 端口,Nginx 提供静态文件服务和代理。
server { listen 80; server_name myapp.com;
# 直接提供静态资源 location /static/ { alias /var/www/myapp/public/; expires 30d; }
# 动态请求代理到 Node location / { proxy_pass http://localhost:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; }}4.2 多服务路由(微服务网关)
根据路径将请求路由到不同后端。
upstream user_service { server 10.0.0.1:8080; server 10.0.0.2:8080;}
upstream order_service { server 10.0.0.3:8080; server 10.0.0.4:8080;}
server { listen 80; server_name api.example.com;
location /api/users/ { proxy_pass http://user_service/; proxy_set_header Host $host; }
location /api/orders/ { proxy_pass http://order_service/; proxy_set_header Host $host; }}4.3 基于域名的虚拟主机反向代理
同一台 Nginx 根据请求域名转发到不同后端。
server { listen 80; server_name blog.example.com; location / { proxy_pass http://blog_backend; }}
server { listen 80; server_name shop.example.com; location / { proxy_pass http://shop_backend; }}5. 性能优化与安全
5.1 性能优化
- 缓冲配置:合理设置
proxy_buffering和缓冲区大小,平衡内存与性能。 - 长连接:启用
keepalive连接池,减少与后端的连接建立开销。upstream backend {server backend1.example.com;server backend2.example.com;keepalive 32; # 每个工作进程保持的空闲连接数}server {location / {proxy_pass http://backend;proxy_http_version 1.1;proxy_set_header Connection "";}} - 压缩:对代理响应启用 Gzip 压缩(如果后端未压缩)。
5.2 安全加固
- 隐藏版本号:
server_tokens off; - 限制请求方法:
if ($request_method !~ ^(GET|HEAD|POST)$) {return 405;}
- IP 白名单:对敏感路径限制访问来源。
location /admin {allow 192.168.1.0/24;deny all;proxy_pass http://backend;}
- 限制请求速率(防止 DDoS):
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;location / {limit_req zone=mylimit burst=20 nodelay;proxy_pass http://backend;}
6. 调试与排错
6.1 查看日志
- 访问日志:
/var/log/nginx/access.log - 错误日志:
/var/log/nginx/error.log
开启详细调试:
error_log /var/log/nginx/error.log debug;6.2 常见问题
| 现象 | 排查方法 |
|---|---|
| 502 Bad Gateway | 后端服务未运行或不可达;检查 proxy_pass 地址、防火墙、后端日志 |
| 504 Gateway Timeout | 后端响应超时,调整 proxy_read_timeout |
| 404 Not Found | proxy_pass 路径拼接错误;检查 location 匹配规则 |
| 无限重定向 | 检查 proxy_set_header Host 是否正确,后端是否强制跳转 |
| WebSocket 连接失败 | 确认 Upgrade 和 Connection 头已设置,后端支持 WebSocket |
7. 总结
Nginx 反向代理是现代 Web 架构的基石之一。通过本文的学习,你应该掌握了从基础配置到负载均衡、SSL 终止、缓存优化等高级特性的使用。
在生产环境中,建议遵循以下最佳实践:
- 将 Nginx 配置纳入版本管理
- 定期更新 Nginx 版本以获取安全补丁
- 监控 Nginx 的访问日志和错误日志
- 结合健康检查确保后端可用性
Nginx 的强大远不止于此,还有更多的模块和功能等待探索。希望这篇指南能帮助你在实战中游刃有余地使用 Nginx 反向代理。
进一步学习资源:
如果这篇文章对你有帮助,欢迎分享给更多人!
部分信息可能已经过时









