正向代理与反向代理
Nginx 的两种核心代理模式,本质区别在于代理的是客户端还是服务器端。
反向代理(Reverse Proxy)
反向代理是 nginx 最常用的模式,代理的是服务器端。
客户端(浏览器) → Nginx(反向代理) → 后端服务器(对客户端不可见) ↑ 客户端知道代理的存在 后端服务器对客户端不可见工作流程:
- 客户端发请求到
api.example.com(实际上是 nginx) - nginx 根据
server_name/location匹配规则,决定转发到哪个后端 - nginx 向后端服务器发起请求,获取响应
- nginx 将响应返回给客户端,客户端以为是 nginx 自己生成的
典型配置:
server { listen 80; server_name api.example.com;
location /api/ { proxy_pass http://127.0.0.1:8765; # 后端服务 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; }}核心用途:
- TLS 终止:nginx 处理 HTTPS,后端只跑 HTTP
- 负载均衡:一个域名分发到多台后端
- 安全隔离:后端服务器不直接暴露
- 缓存/压缩:nginx 层处理,减轻后端压力
正向代理(Forward Proxy)
正向代理代理的是客户端,客户端主动通过代理去访问外部资源。
客户端(配置代理) → Nginx(正向代理) → 目标服务器(如 google.com) ↑ ↑ 知道代理的存在 看到的是代理的 IP,不知道真实客户端工作流程:
- 客户端配置代理指向 nginx,请求
http://google.com - nginx 解析目标域名,向目标服务器发起请求
- 将响应返回给客户端
典型配置:
server { listen 8888;
# 正向代理需要 resolver(nginx 自己不查 DNS) resolver 8.8.8.8;
location / { proxy_pass http://$http_host$request_uri; }}关键区别: 正向代理中,nginx 需要自己解析域名(所以需要 resolver 指令),目标服务器看到的是 nginx 的 IP,看不到真实客户端。
对比总结
| 维度 | 反向代理 | 正向代理 |
|---|---|---|
| 代理谁 | 代理后端服务器 | 代理客户端 |
| 客户端是否知情 | 不知道(透明) | 需要主动配置 |
| 目标服务器看到谁 | 看到 nginx(不知道后端在哪) | 看到 nginx(不知道客户端是谁) |
| DNS 解析 | 后端通常是固定 IP/localhost | nginx 需要解析目标域名 |
| 典型场景 | Web 服务暴露、负载均衡 | 科学上网、内网访问外网 |
| HTTPS | nginx 做 TLS 终止即可 | 需要 CONNECT 隧道(nginx 原生不支持) |
原理剖析
两者的核心区别在于谁发起连接、连接谁,这决定了整个工作原理。
反向代理原理
客户端 ──TCP连接──→ Nginx ──TCP连接──→ 后端服务器 ① ② ③-
两段独立连接:客户端与 nginx 建立一条 TCP 连接(①→②),nginx 与后端建立另一条 TCP 连接(②→③)。两条连接完全独立,互不知道对方的存在。
-
请求改写与转发:nginx 收到客户端请求后,根据配置规则(
location、upstream)决定转发到哪个后端,然后自己作为客户端向后端发起 HTTP 请求。后端看到的是一个来自 nginx 的请求,完全不知道真实客户端是谁。 -
响应中继:后端返回响应给 nginx,nginx 再把响应传回客户端。整个过程中客户端看到的 IP 是 nginx 的 IP,永远不会感知后端的存在。
本质: nginx 充当了一个”门面”,对外接收请求,对内代替客户端向后端发请求。客户端以为 nginx 就是服务端本身。
正向代理原理
客户端 ──TCP连接──→ Nginx ──TCP连接──→ 目标服务器(google.com) ① ② ③-
客户端主动告知目标:客户端(如浏览器)配置了代理地址,发请求时不是直接连目标服务器,而是把目标 URL 发给 nginx。HTTP 请求行是
GET http://google.com/ HTTP/1.1(完整的绝对 URL),而不是反向代理中的GET / HTTP/1.1。 -
nginx 代为解析和连接:nginx 从请求中解析出目标域名,自己去做 DNS 解析(所以需要
resolver指令),然后代替客户端向目标服务器发起连接。目标服务器看到的是 nginx 的 IP,不知道真实客户端。 -
响应回传:目标服务器返回内容给 nginx,nginx 再传回客户端。
本质: nginx 充当了客户端的”替身”,客户端不出面,让 nginx 代替自己去访问外部资源。
关键原理差异
| 原理层面 | 反向代理 | 正向代理 |
|---|---|---|
| HTTP 请求行 | GET /path HTTP/1.1(相对路径) | GET http://目标/路径 HTTP/1.1(绝对 URL) |
| DNS 解析者 | 不需要(后端地址在配置里写死) | nginx 必须自己解析目标域名 |
| nginx 的角色 | 对外是服务端,对内是客户端 | 对外是客户端,对内也是客户端 |
| 谁决定目标 | nginx 的配置规则决定 | 客户端指定 |
HTTPS 场景下的差异
HTTPS 场景最能体现两者的本质区别。
反向代理 HTTPS
客户端 ──TLS──→ Nginx ──HTTP──→ 后端 ↑ nginx 终止 TLS,解密后明文转发nginx 手握域名的证书,合法地做 TLS 终止。客户端信任这个证书,所以完全透明。
正向代理 HTTPS
客户端 ──TLS隧道──→ Nginx ──TLS──→ 目标服务器 ↑ 客户端要求建立 CONNECT 隧道客户端通过 CONNECT google.com:443 请求 nginx 建立一条纯 TCP 隧道,之后数据双向透传,nginx 看不到明文内容。这就是为什么 nginx 做正向代理 HTTPS 需要额外模块——原生只支持 HTTP 层的代理,不支持 CONNECT 隧道。
补充: nginx 不原生支持 HTTP CONNECT 方法(正向代理 HTTPS 必需)。用 nginx 做 HTTPS 正向代理通常需要客户端信任 nginx 的 CA 证书(MITM 方式),或者用专门的工具如
squid、3proxy。
Nginx 的其他核心功能
除了正向/反向代理,nginx 还有很多实用功能:
负载均衡(Load Balancing)
反向代理的进阶用法,把请求分发到多台后端:
upstream backend { server 10.0.0.1:8080 weight=3; # 权重 3,承担更多流量 server 10.0.0.2:8080 weight=1; server 10.0.0.3:8080 backup; # 备用,前两台挂了才启用}
server { location / { proxy_pass http://backend; }}支持多种策略:轮询(默认)、加权轮询、ip_hash(会话保持)、least_conn(最少连接)。
静态文件服务
nginx 最擅长的事——直接提供静态内容,效率极高:
server { location /static/ { root /var/www/html; expires 30d; # 浏览器缓存 30 天 gzip on; # 压缩传输 }}缓存(Cache)
缓存后端响应,减轻后端压力:
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m;
server { location / { proxy_pass http://backend; proxy_cache my_cache; proxy_cache_valid 200 10m; # 200 响应缓存 10 分钟 }}限流(Rate Limiting)
防止突发流量压垮后端:
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
server { location /api/ { limit_req zone=api burst=20 nodelay; # 每秒 10 次,突发允许 20 proxy_pass http://backend; }}TLS 终止(SSL Termination)
统一管理 HTTPS 证书,后端只跑 HTTP:
server { listen 443 ssl; ssl_certificate /etc/ssl/cert.pem; ssl_certificate_key /etc/ssl/key.pem; ssl_protocols TLSv1.2 TLSv1.3;
location / { proxy_pass http://127.0.0.1:8080; # 后端是纯 HTTP }}WebSocket 代理
location /ws/ { proxy_pass http://backend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade";}访问控制(ACL)
location /admin/ { allow 10.0.0.0/24; # 只允许内网 deny all; proxy_pass http://backend;}URL 重写 / 重定向
# 重写rewrite ^/old/(.*)$ /new/$1 permanent;
# 重定向location /legacy { return 301 https://new-site.com$request_uri;}HTTP/2 & HTTP/3 支持
listen 443 ssl;http2 on; # HTTP/2gRPC 代理
location / { grpc_pass grpc://backend:50051;}功能总览
| 功能 | 一句话描述 |
|---|---|
| 负载均衡 | 请求分发到多台后端 |
| 静态服务 | 高效提供文件 |
| 缓存 | 缓存后端响应减少压力 |
| 限流 | 控制请求速率防雪崩 |
| TLS 终止 | 统一管理 HTTPS |
| WebSocket | 代理长连接 |
| 访问控制 | IP 黑白名单 |
| URL 重写 | 路由映射和重定向 |
| HTTP/2&3 | 现代协议支持 |
| gRPC | 高性能 RPC 代理 |
本质上,nginx 就是一个高性能的 HTTP 流量控制器——正向/反向代理是它的核心能力,其他功能都是围绕”如何更好地处理和转发流量”展开的。
一句话区分两种代理模式:正向代理隐藏客户端,反向代理隐藏服务器。