反向代理在实际生产环境中有非常广泛的应用,我列举几个最常见的场景,每个都配有配置示例:
场景一:负载均衡(最核心的应用)
将请求分发到多台后端服务器,提升系统处理能力和可用性。
# Nginx 反向代理负载均衡配置
upstream backend_servers {
server 192.168.1.10:8080 weight=3; # 权重3,处理更多请求
server 192.168.1.11:8080 weight=2;
server 192.168.1.12:8080 backup; # 备用服务器
}
server {
listen 80;
server_name www.example.com;
location / {
proxy_pass http://backend_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
效果:
- 三台服务器分担压力
- 一台故障自动剔除
- 高峰期自动扩容(配合云服务)
场景二:动静分离
将动态请求(如 PHP、Java)和静态文件(图片、CSS、JS)分开处理,各取所长。
server {
listen 80;
server_name www.example.com;
# 静态文件直接由 Nginx 处理(高性能)
location ~* \.(jpg|png|css|js|html)$ {
root /data/static;
expires 30d; # 浏览器缓存30天
access_log off; # 静态文件不记录日志
}
# 动态请求转发给后端
location /api/ {
proxy_pass http://java_backend:8080;
proxy_set_header Host $host;
}
location ~ \.php$ {
proxy_pass http://php_fpm:9000;
}
}
效果:
- 静态文件 Nginx 直接返回,性能极高
- 动态请求交给专门的应用服务器
- 整体响应时间降低 50% 以上
场景三:SSL 终结(HTTPS 卸载)
将 HTTPS 加解密的压力集中在反向代理层,后端服务器只需处理 HTTP。
server {
listen 443 ssl http2;
server_name www.example.com;
# SSL 证书配置(只在反向代理层配置一次)
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
ssl_protocols TLSv1.2 TLSv1.3;
# 后端服务器只处理 HTTP(无需关心证书)
location / {
proxy_pass http://backend_servers;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
}
}
效果:
- 后端服务器无需处理 SSL,简化配置
- 证书统一管理,便于续期
- 减轻后端 CPU 负担(SSL 加解密很耗性能)
场景四:缓存加速
反向代理可以缓存后端服务器的响应,减少重复请求对后端的压力。
proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=my_cache:10m max_size=10g;
server {
listen 80;
server_name www.example.com;
location / {
# 启用缓存
proxy_cache my_cache;
proxy_cache_key "$scheme$request_method$host$request_uri";
proxy_cache_valid 200 302 10m; # 成功响应缓存10分钟
proxy_cache_valid 404 1m; # 404页面缓存1分钟
proxy_pass http://backend_servers;
# 添加缓存状态头(用于调试)
add_header X-Cache-Status $upstream_cache_status;
}
}
效果:
- 热门页面直接从缓存返回,毫秒级响应
- 后端服务器压力减少 70% 以上
- 抗住突发流量(如秒杀、热点新闻)
场景五:统一认证和授权
将认证逻辑集中到反向代理层,后端服务无需重复实现。
server {
listen 80;
server_name admin.example.com;
# 统一认证
location / {
auth_request /auth; # 先验证身份
# 验证通过后转发给后端
proxy_pass http://internal_admin_servers;
}
# 内部认证接口
location = /auth {
internal;
proxy_pass http://auth_service:8080/validate;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;
}
# 认证失败跳转登录页
error_page 401 = @error401;
location @error401 {
return 302 https://login.example.com;
}
}
效果:
- 所有服务统一接入认证
- 新服务无需单独实现登录逻辑
- 认证策略变更只需修改反向代理层
场景六:微服务 API 网关
根据请求路径,将请求路由到不同的微服务。
server {
listen 80;
server_name api.example.com;
# 用户服务
location /api/user/ {
proxy_pass http://user_service:8081/;
rewrite ^/api/user/(.*) /$1 break;
}
# 订单服务
location /api/order/ {
proxy_pass http://order_service:8082/;
}
# 商品服务
location /api/product/ {
proxy_pass http://product_service:8083/;
}
# 搜索服务
location /api/search/ {
proxy_pass http://search_service:8084/;
}
# 文件上传服务(特殊处理)
location /api/upload/ {
client_max_body_size 100m; # 上传大小限制
proxy_pass http://upload_service:8085/;
}
}
效果:
- 客户端只需知道一个域名
- 服务拆分对客户端透明
- 便于版本升级和灰度发布
场景七:跨域请求处理
解决前端跨域问题,由反向代理转发请求。
server {
listen 80;
server_name frontend.example.com;
# 前端静态文件
location / {
root /data/frontend;
index index.html;
}
# API 请求转发(解决跨域)
location /api/ {
proxy_pass http://backend.example.com:8080/api/;
# 跨域头设置
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept";
# 预检请求处理
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept";
add_header Content-Length 0;
add_header Content-Type text/plain;
return 204;
}
}
}
效果:
- 前后端分离时无需配置 CORS
- 统一处理跨域逻辑
- 更安全(可以精确控制允许的域名)
场景八:灰度发布与 A/B 测试
根据特定规则(如 IP、Cookie)将部分用户引流到新版本服务。
split_clients "${remote_addr}${http_user_agent}" $upstream_select {
10% new_backend; # 10% 流量到新版本
90% old_backend; # 90% 流量到老版本
}
upstream old_backend {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}
upstream new_backend {
server 192.168.1.20:8080;
}
server {
listen 80;
server_name www.example.com;
location / {
proxy_pass http://$upstream_select;
# 添加标识头,便于调试
add_header X-Backend $upstream_select;
}
}
效果:
- 风险可控地发布新版本
- 收集用户反馈后再全量发布
- 可以根据需要进行 A/B 测试
发表回复