← blog DevOps & 云原生 · 2026-07-04

Nginx 详解

深入理解 Nginx 正向代理与反向代理的工作原理、原理剖析,以及负载均衡、缓存、限流等核心功能。

10 min read

正向代理与反向代理

Nginx 的两种核心代理模式,本质区别在于代理的是客户端还是服务器端。

反向代理(Reverse Proxy)

反向代理是 nginx 最常用的模式,代理的是服务器端。

graph LR
    C["客户端(浏览器)"] --> N["Nginx(反向代理)"]
    N --> B["后端服务器(对客户端不可见)"]
    Note["客户端知道代理的存在<br/>后端服务器对客户端不可见"] -.-> N

工作流程:

  1. 客户端发请求到 api.example.com(实际上是 nginx)
  2. nginx 根据 server_name / location 匹配规则,决定转发到哪个后端
  3. nginx 向后端服务器发起请求,获取响应
  4. 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)

正向代理代理的是客户端,客户端主动通过代理去访问外部资源。

graph LR
    C["客户端(配置代理)"] --> N["Nginx(正向代理)"]
    N --> T["目标服务器(如 google.com)"]
    CNote["知道代理的存在"] -.-> C
    TNote["看到的是代理的 IP,不知道真实客户端"] -.-> T

工作流程:

  1. 客户端配置代理指向 nginx,请求 http://google.com
  2. nginx 解析目标域名,向目标服务器发起请求
  3. 将响应返回给客户端

典型配置:

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/localhostnginx 需要解析目标域名
典型场景Web 服务暴露、负载均衡科学上网、内网访问外网
HTTPSnginx 做 TLS 终止即可需要 CONNECT 隧道(nginx 原生不支持)

原理剖析

两者的核心区别在于谁发起连接、连接谁,这决定了整个工作原理。

反向代理原理

graph LR
    C["客户端"] -->|"① TCP连接"| N["Nginx (②)"]
    N -->|"③ TCP连接"| B["后端服务器"]
  1. 两段独立连接:客户端与 nginx 建立一条 TCP 连接(①→②),nginx 与后端建立另一条 TCP 连接(②→③)。两条连接完全独立,互不知道对方的存在。

  2. 请求改写与转发:nginx 收到客户端请求后,根据配置规则(location、upstream)决定转发到哪个后端,然后自己作为客户端向后端发起 HTTP 请求。后端看到的是一个来自 nginx 的请求,完全不知道真实客户端是谁。

  3. 响应中继:后端返回响应给 nginx,nginx 再把响应传回客户端。整个过程中客户端看到的 IP 是 nginx 的 IP,永远不会感知后端的存在。

本质: nginx 充当了一个”门面”,对外接收请求,对内代替客户端向后端发请求。客户端以为 nginx 就是服务端本身。

正向代理原理

graph LR
    C["客户端"] -->|"① TCP连接"| N["Nginx (②)"]
    N -->|"③ TCP连接"| T["目标服务器(google.com)"]
  1. 客户端主动告知目标:客户端(如浏览器)配置了代理地址,发请求时不是直接连目标服务器,而是把目标 URL 发给 nginx。HTTP 请求行是 GET http://google.com/ HTTP/1.1(完整的绝对 URL),而不是反向代理中的 GET / HTTP/1.1。

  2. nginx 代为解析和连接:nginx 从请求中解析出目标域名,自己去做 DNS 解析(所以需要 resolver 指令),然后代替客户端向目标服务器发起连接。目标服务器看到的是 nginx 的 IP,不知道真实客户端。

  3. 响应回传:目标服务器返回内容给 nginx,nginx 再传回客户端。

本质: nginx 充当了客户端的”替身”,客户端不出面,让 nginx 代替自己去访问外部资源。

关键原理差异

原理层面反向代理正向代理
HTTP 请求行GET /path HTTP/1.1(相对路径)GET http://目标/路径 HTTP/1.1(绝对 URL)
DNS 解析者不需要(后端地址在配置里写死)nginx 必须自己解析目标域名
nginx 的角色对外是服务端,对内是客户端对外是客户端,对内也是客户端
谁决定目标nginx 的配置规则决定客户端指定

HTTPS 场景下的差异

HTTPS 场景最能体现两者的本质区别。

反向代理 HTTPS

graph LR
    C["客户端"] -->|"TLS"| N["Nginx"]
    N -->|"HTTP"| B["后端"]
    Note["nginx 终止 TLS,解密后明文转发"] -.-> N

nginx 手握域名的证书,合法地做 TLS 终止。客户端信任这个证书,所以完全透明。

正向代理 HTTPS

graph LR
    C["客户端"] -->|"TLS隧道"| N["Nginx"]
    N -->|"TLS"| T["目标服务器"]
    Note["客户端要求建立 CONNECT 隧道"] -.-> C

客户端通过 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/2

gRPC 代理

location / {
    grpc_pass grpc://backend:50051;
}

功能总览

功能一句话描述
负载均衡请求分发到多台后端
静态服务高效提供文件
缓存缓存后端响应减少压力
限流控制请求速率防雪崩
TLS 终止统一管理 HTTPS
WebSocket代理长连接
访问控制IP 黑白名单
URL 重写路由映射和重定向
HTTP/2&3现代协议支持
gRPC高性能 RPC 代理

本质上,nginx 就是一个高性能的 HTTP 流量控制器——正向/反向代理是它的核心能力,其他功能都是围绕”如何更好地处理和转发流量”展开的。

一句话区分两种代理模式:正向代理隐藏客户端,反向代理隐藏服务器。

Sources

No external sources for this entry.

Related