Nginx 反向代理、重写与 WebSocket
nginx 反向代理可灵活地转发请求并修改 URL 路径,常用于隐藏后端服务真实路径、统一入口域名或适配不同服务的路径规则
基础反向代理(代理单个目标服务)
将 http://your-domain.com 的请求代理到本地或远程的目标服务(如 http://127.0.0.1:3000)
shell
server {
listen 80;
server_name your-domain.com; # 你的域名
# 反向代理配置
location / {
proxy_pass http://127.0.0.1:3000; # 目标服务地址(必填)
# 可选但推荐的代理参数(传递客户端信息给目标服务)
proxy_set_header Host $host; # 传递客户端请求的 Host 头
proxy_set_header X-Real-IP $remote_addr; # 传递客户端真实 IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 传递代理链 IP
proxy_set_header X-Forwarded-Proto $scheme; # 传递协议(http/https)
}
}代理到不同路径(按 URL 路径区分服务)
将不同路径的请求代理到不同服务(例如 /api 代理到后端 API,/ 代理到前端页面)。
shell
server {
listen 80;
server_name your-domain.com;
# API 接口:代理到 3000 端口的后端服务
location /api {
proxy_pass http://127.0.0.1:3000; # 注意:目标地址后是否加 / 会影响路径拼接
# 若 proxy_pass 目标地址以 / 结尾,(如 http://127.0.0.1:3000/),则请求 /api/user 会被代理为 http://127.0.0.1:3000/user
# 若 proxy_pass 目标地址不以 / 结尾,则代理为 http://127.0.0.1:3000/api/user。
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# 前端页面:代理到 8080 端口的前端服务
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}HTTPS 反向代理(带 SSL 证书)
将 https://your-domain.com 代理到目标服务,并配置 SSL 证书(需提前准备证书文件)
shell
server {
listen 443 ssl;
server_name your-domain.com;
# SSL 证书配置
ssl_certificate /path/to/your/cert.pem; # 证书公钥
ssl_certificate_key /path/to/your/key.pem; # 证书私钥
# 可选:SSL 优化参数
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
# 反向代理配置
location / {
proxy_pass http://127.0.0.1:3000; # 目标服务(可以是 http 或 https)
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme; # 传递 https 协议
}
}
# 可选:将 http 强制跳转至 https
server {
listen 80;
server_name your-domain.com;
return 301 https://$host$request_uri;
}说明: 与「反向代理」重复的
upstream轮询示例已移除;多后端调度、权重与健康检查等完整内容见本目录 《05、负载均衡详解》(对应原「负载均衡详解」一章)。
代理 WebSocket 服务
WebSocket 需要特殊配置以支持长连接(如代理聊天、实时通知服务)。
shell
server {
listen 80;
server_name your-domain.com;
location /ws {
proxy_pass http://127.0.0.1:8080; # WebSocket 服务地址
# WebSocket 必需参数
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# 其他常规参数
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}路径重写
shell
# 语法
rewrite 正则表达式 目标路径 [flag];
# flag 值
last:完成重写后,不再匹配后续规则,重新查找 location
break:完成重写后,停止后续规则,使用当前 location
redirect:临时重定向(302)
permanent:永久重定向(301)
# 场景一:将 /api/ 前缀转发到后端的 /
# 比如:把 example.com/api/user 转发到 backend:8080/user
location /api/ {
# 去掉路径中的 /api 前缀(注意正则后的 /)
rewrite ^/api/(.*)$ /$1 break;
proxy_pass http://backend:8080;
# 其他 proxy 头配置...
}
# 场景二:将 / 前缀转发到后端的 /api/
# 比如:把 example.com/user 转发到 backend:8080/api/user
location / {
# 将根路径重写为 /api/
rewrite ^/$ /api/ last;
proxy_pass http://backend:8080;
}
# 场景三:将多路径映射到不同后端服务
# 比如:将不同的路径前缀重写成 / ,然后匹配不同服务(场景一的灵活使用)
# /user 路径转发到用户服务
location /user/ {
rewrite ^/user/(.*)$ /$1 break;
proxy_pass http://user_service:8081;
}
# /order 路径转发到订单服务
location /order/ {
rewrite ^/order/(.*)$ /v2/$1 break; # 同时添加后端的 /v2 前缀
proxy_pass http://order_service:8082;
}
# 场景四:带参数的路径重写
# 比如:将 /search?key=xxx 重写为 /query?keyword=xxx
location /search {
rewrite ^/search$ /query?keyword=$arg_key last;
proxy_pass http://search_service:8083;
}注意
- server 块儿配置通常在 /etc/nginx/conf.d/ 目录下的 域名.conf 文件中定义,也就是分散定义在子配置文件中,便于区分管理
- 任何配置变更后,需执行nginx -t测试配置语法是否正确,无误后再用systemctl reload nginx重启服务。
- proxy_pass 末尾的 / 影响
shell
# 带 / (相当于把 /api/ 重写为 /)
location /api/ {
proxy_pass http://backend:8080/; # /api/user → http://backend:8080/user
}
# 不加 /(正常匹配,不重写)
location /api/ {
proxy_pass http://backend:8080; # /api/user → http://backend:8080/api/user
}