反向代理核心:客户端请求 Nginx,Nginx 转发请求到后端真实业务服务器,再把后端响应返回客户端。分为七层 HTTP 反向代理(http {} 块) 和四层 TCP 反向代理(stream {} 块,前面 MySQL 那种),下面重点是 Web 最常用的七层反向代理。
前置说明
模块:
ngx_http_proxy_module,Nginx 默认自带,无需额外编译位置:配置写在
http {}内部,server {}/location {}里面核心指令:
proxy_pass
一、最简示例(单后端服务)
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
# 虚拟主机
server {
listen 80;
server_name demo.example.com; # 域名
# 所有请求转发到后端 http://127.0.0.1:8080
location / {
proxy_pass http://127.0.0.1:8080;
}
}
}
⚠️ proxy_pass 末尾
/坑点
proxy_pass http://127.0.0.1:8080不带斜杠:/api/xxx→ 转发/api/xxx
proxy_pass http://127.0.0.1:8080/带斜杠:/api/xxx→ 转发/xxx路径替换场景才用末尾/,绝大多数业务推荐不带斜杠。
二、生产推荐完整版(带请求头透传,非常重要)
后端应用需要获取真实客户端 IP、域名、协议,必须配置 proxy_set_header:
server {
listen 80;
server_name demo.example.com;
location / {
proxy_pass http://127.0.0.1:8080;
# 透传客户端真实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;
# 传递原始协议 http/https
proxy_set_header X-Forwarded-Proto $scheme;
# 超时参数调优
proxy_connect_timeout 10s; # Nginx连接后端超时
proxy_read_timeout 60s; # 后端返回数据超时(慢接口调大)
proxy_send_timeout 60s;
proxy_buffering on; # 响应缓冲
proxy_buffer_size 4k;
proxy_buffers 8 4k;
}
}
后端 Java/SpringBoot 可以读取 X-Real-IP 获取真实客户端 IP。
三、反向代理 + 后端集群负载均衡(upstream)
多个业务节点,Nginx 七层负载均衡 + 反向代理组合,生产最常用:
http {
upstream web_cluster {
# 调度策略:默认轮询;least_conn最少连接;ip_hash会话保持
least_conn;
server 10.0.1.10:8080 weight=5 max_fails=3 fail_timeout=30s;
server 10.0.1.11:8080 weight=5 max_fails=3 fail_timeout=30s;
server 10.0.1.12:8080 backup; # 备用节点
}
server {
listen 80;
server_name demo.example.com;
location / {
proxy_pass http://web_cluster; # 转发到upstream集群名
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;
}
}
}
四、按路径分流反向代理(不同 path 转发不同后端)
server {
listen 80;
server_name demo.example.com;
# 前端静态页面
location / {
proxy_pass http://10.0.1.10:8080;
proxy_set_header Host $host;
}
# api接口转发到后端Java服务
location /api/ {
proxy_pass http://10.0.1.11:9090;
proxy_set_header Host $host;
}
# 图片单独转发
location /static/ {
proxy_pass http://10.0.1.12:8888;
proxy_set_header Host $host;
}
}
五、HTTPS 反向代理(Nginx 解密,后端 http)
server {
listen 443 ssl;
server_name demo.example.com;
ssl_certificate /etc/nginx/ssl/demo.crt;
ssl_certificate_key /etc/nginx/ssl/demo.key;
location / {
proxy_pass http://10.0.1.10:8080;
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;
}
}
六、四层 TCP 反向代理(stream 块,前面 MySQL 属于这类)
不属于 http 反向代理,不解析 http 协议,只转发 TCP 流量
stream {
upstream mysql_backend {
server 10.0.1.10:3306;
}
server {
listen 3306;
proxy_pass mysql_backend;
proxy_connect_timeout 10s;
proxy_timeout 600s;
}
}
七、配置校验与重载命令
# 检查配置语法是否正确
nginx -t
# 平滑重载(不中断现有连接)
nginx -s reload
# 查看nginx版本和编译模块
nginx -V
八、常见坑
Host 头丢失:后端拿不到域名,必须配置
proxy_set_header Host $host;真实 IP 获取不到:缺少
X-Real-IP/X-Forwarded-Forproxy_pass 斜杠问题,路径匹配错乱
超时时间太短:大文件上传、报表导出接口超时 504,调大
proxy_read_timeout跨域问题:Nginx 反向代理不会自动处理跨域,跨域头需要后端或者 Nginx 添加
add_header
九、扩展:Nginx 添加跨域头示例(location 内)
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
add_header Access-Control-Allow-Headers *;
if ($request_method = 'OPTIONS') {
return 204;
}本文原创作者:易君召,详见:https://www.yijunzhao.cc/about,转载请注明出处。
原文链接
欢迎访问