【Linux】Nginx - 反向代理
一、核心概念
反向代理 :代理服务器接收客户端请求,转发给后端服务器(如 Tomcat、Node.js、Golang 服务等),并将响应返回给客户端,客户端无需感知后端服务器的存在。
对比正向代理:
- 正向代理:代理客户端,隐藏客户端身份(如 VPN)。
- 反向代理:代理服务端,隐藏服务器身份,提供统一入口。
二、应用场景
- 负载均衡:将请求分发到多个后端服务器。
- 动静分离:静态资源由 Nginx 处理,动态请求转发给后端。
- 统一入口 :多个服务通过不同路径(
location)对外提供。 - SSL 终端:由 Nginx 统一处理 HTTPS 加解密,后端使用 HTTP。
- 缓存加速:缓存后端响应,减少后端压力。
- 安全防护:隐藏后端服务器 IP,限制访问频率。
- 跨域处理:在反向代理层配置跨域头。
三、基础配置示例
nginx
http {
upstream backend {
server 10.0.0.1:8080 weight=3;
server 10.0.0.2:8080;
keepalive 32;
}
server {
listen 80;
server_name example.com;
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_connect_timeout 5s;
proxy_read_timeout 30s;
}
# 静态文件处理
location ~* \.(jpg|css|js)$ {
root /var/www/static;
expires 30d;
}
}
}
四、重难点详解
1. 负载均衡策略
- 轮询(默认):按顺序分配。
- 权重(weight):指定服务器权重。
- IP Hash:同一 IP 固定到同一后端(解决会话保持)。
- 最少连接(least_conn):优先发给连接数最少的服务器。
2. 会话保持
- 使用
ip_hash或hash $cookie_jsessionid。 - 或后端使用 Redis 等共享 Session。
3. 动态 upstream 更新
- 传统配置需重载 Nginx。
- 可使用
nginx plus或openresty动态更新。 - 或结合 Consul + nginx-upsync-module。
4. 缓冲区优化
nginx
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
proxy_busy_buffers_size 16k;
- 过大:占用内存过多。
- 过小:频繁 IO,影响性能。
5. 长连接管理
nginx
upstream backend {
server 10.0.0.1:8080;
keepalive 32; # 连接池大小
}
location / {
proxy_http_version 1.1;
proxy_set_header Connection "";
}
五、常见问题与解决方案
1. 502 Bad Gateway
-
原因:后端服务不可用、连接被拒绝、进程崩溃。
-
排查:
bashcurl -I http://后端IP:端口 netstat -ant | grep 端口 tail -f /var/log/nginx/error.log
2. 504 Gateway Timeout
-
原因:后端处理超时。
-
解决:
nginxproxy_read_timeout 60s; proxy_send_timeout 60s;
3. 请求头丢失
-
现象:后端获取不到真实 IP 或 Host。
-
解决:
nginxproxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
4. URL 重写问题
-
配置:
nginxlocation /api/ { # 注意结尾带/与不带/的区别 proxy_pass http://backend/; # 会将/api/替换为/ }
5. WebSocket 代理
nginx
location /ws/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
6. 大文件上传失败
nginx
client_max_body_size 100m;
proxy_request_buffering off; # 禁用缓冲,直接流式传输
六、问题对项目的影响
1. 性能影响
- 缓冲区设置不当:内存占用高或响应慢。
- 负载不均:某些后端服务器过载。
2. 可用性影响
- 单点故障:Nginx 本身成为单点(需配合 Keepalived 高可用)。
- 后端健康检查失效:请求仍会转发到已宕机的服务。
3. 业务异常表现
- 用户会话中断:负载均衡策略导致 Session 丢失。
- 静态资源加载失败:路径配置错误或权限问题。
- API 响应变慢或超时:代理超时设置不合理。
七、最佳实践建议
-
始终配置健康检查(Nginx Plus 或开源模块)。
-
日志记录完整信息:
nginxlog_format proxy '$remote_addr - $upstream_addr - $request_time'; access_log /var/log/nginx/access.log proxy; -
限制并发与速率:
nginxlimit_conn_zone $binary_remote_addr zone=perip:10m; limit_req_zone $binary_remote_addr zone=ratelimit:10m rate=10r/s; -
使用变量提高灵活性:
nginxset $backend "http://backend_service"; proxy_pass $backend; -
定期监控指标:
nginx.status.active(活跃连接)nginx.status.accepts(接收请求数)- 后端响应时间分布
八、调试命令
bash
# 检查配置语法
nginx -t
# 热重载配置
nginx -s reload
# 查看连接状态
ss -tpn | grep nginx
# 实时监控错误日志
tail -f /var/log/nginx/error.log
# 压力测试(检查代理性能)
ab -n 1000 -c 10 http://example.com/api/test