反向代理位于客户端和后端服务器之间,转发请求并返回响应。Nginx 是 2026 年这一角色最流行的选择——它以最少的配置处理 SSL 终止、负载均衡、缓存和 WebSocket 代理。本指南涵盖了所有你需要的生产就绪模式。
基本反向代理设置
最简单的反向代理将所有请求转发到单个后端服务器。关键头部确保你的后端看到真实的客户端 IP 和协议。
# Basic reverse proxy configuration
server {
listen 80;
server_name example.com www.example.com;
location / {
proxy_pass http://localhost:3000;
# Pass original request headers to the backend
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;
# Timeouts (seconds)
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# Buffer settings
proxy_buffering on;
proxy_buffer_size 16k;
proxy_buffers 4 16k;
}
}SSL/TLS 终止
在 Nginx 处进行 SSL 终止意味着你的后端服务器只需在内部处理 HTTP,简化了它们的配置。Nginx 处理加密开销。
# Full SSL/TLS reverse proxy with HTTP redirect
server {
listen 80;
server_name example.com www.example.com;
# Permanent redirect all HTTP traffic to HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com www.example.com;
# SSL certificate (Let's Encrypt)
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# Modern SSL settings (2026 recommended)
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers off;
# SSL session cache
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
# HSTS: tell browsers to always use HTTPS (6 months)
add_header Strict-Transport-Security "max-age=15768000" always;
# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
location / {
proxy_pass http://localhost:3000;
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;
}
}上游块和负载均衡
upstream 块定义了一组后端服务器。Nginx 支持轮询、最少连接和 IP 哈希负载均衡算法。
# Load balancing across multiple backends
upstream app_servers {
# Default: round-robin
server 10.0.0.1:3000;
server 10.0.0.2:3000;
server 10.0.0.3:3000;
# Least connections algorithm
# least_conn;
# IP hash (sticky sessions)
# ip_hash;
# Weighted distribution
# server 10.0.0.1:3000 weight=3;
# server 10.0.0.2:3000 weight=1;
# Health checks (Nginx Plus only; use passive for open-source)
server 10.0.0.3:3000 max_fails=3 fail_timeout=30s;
# Keepalive connections to backends
keepalive 32;
}
server {
listen 443 ssl http2;
server_name example.com;
# ... SSL config omitted for brevity ...
location / {
proxy_pass http://app_servers;
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_set_header Connection "";
proxy_http_version 1.1;
proxy_connect_timeout 5s;
proxy_read_timeout 60s;
}
}WebSocket 代理
WebSocket 连接需要特殊处理,因为它们从 HTTP 升级为持久 TCP 连接。必须转发 Upgrade 和 Connection 头。
# WebSocket proxy configuration
server {
listen 443 ssl http2;
server_name ws.example.com;
# ... SSL config ...
location /ws/ {
proxy_pass http://localhost:8080;
# WebSocket upgrade headers
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;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Long timeout for persistent connections
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
# Regular HTTP traffic on the same server
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}代理缓存
Nginx 可以缓存后端响应,以减少可缓存内容的负载和延迟。
# Caching with proxy_cache
proxy_cache_path /var/cache/nginx
levels=1:2
keys_zone=app_cache:10m
max_size=1g
inactive=60m
use_temp_path=off;
server {
listen 443 ssl http2;
server_name example.com;
# ... SSL config ...
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
# Enable cache
proxy_cache app_cache;
proxy_cache_key "$scheme$request_method$host$request_uri";
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
# Return stale content while refreshing
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
# Add cache status header for debugging
add_header X-Cache-Status $upstream_cache_status;
# Don't cache if Cookie or Authorization header present
proxy_cache_bypass $http_cookie $http_authorization;
proxy_no_cache $http_cookie $http_authorization;
}
# Bypass cache for API routes
location /api/ {
proxy_pass http://localhost:3000;
proxy_cache_bypass 1;
proxy_no_cache 1;
}
}快速参考:关键指令
| Directive | Description |
|---|---|
| proxy_pass | Upstream backend URL |
| proxy_set_header | Modify/add request headers to backend |
| proxy_connect_timeout | Time to establish connection to backend |
| proxy_read_timeout | Time to read response from backend |
| proxy_send_timeout | Time to send request to backend |
| proxy_buffering | Buffer backend responses (on/off) |
| proxy_cache | Enable caching using a named cache zone |
| proxy_cache_valid | Cache duration per status code |
| proxy_http_version | HTTP version for backend (set 1.1 for keepalive) |
| upstream | Define a pool of backend servers |
| keepalive | Max idle keepalive connections to backends |
生产最佳实践
- 重载前始终测试配置:nginx -t。在生产环境中永远不要不测试就重载。
- 使用 proxy_set_header X-Forwarded-Proto $scheme,让后端知道原始请求是 HTTP 还是 HTTPS。
- 设置适当的超时。默认的 proxy_read_timeout 是 60s——对于长时间运行的请求(文件上传、报告)需要增加。
- 在上游块中使用 proxy_http_version 1.1 和 keepalive 启用到后端的 keepalive 连接,以获得更好的性能。
- 监控 /var/log/nginx/error.log 和 access.log。使用 logrotate 设置日志轮换。
常见问题
如何将真实客户端 IP 传递给后端?
添加这些头部:proxy_set_header X-Real-IP $remote_addr 和 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for。然后在后端,读取 X-Real-IP(直接客户端)或 X-Forwarded-For 中的第一个条目。如果使用多个代理,配置受信任的代理 IP。
如何处理具有不同路径的多个后端?
使用多个 location 块:location /api/ { proxy_pass http://api-server:8080; } 和 location /app/ { proxy_pass http://app-server:3000; }。proxy_pass 中的尾部斜杠很重要——http://backend/api/ 在转发前会去掉 /api 前缀。
proxy_pass 有无尾部斜杠有什么区别?
无尾部斜杠:proxy_pass http://backend——包含 location 路径的完整 URI 被转发。有尾部斜杠:proxy_pass http://backend/——location 路径前缀被移除。例如:带有 proxy_pass http://backend/ 的 location /app/ 会将 /app/page 作为 /page 转发给后端。
如何调试代理连接问题?
首先检查 /var/log/nginx/error.log。常见问题:(1) upstream connection refused——后端未运行或端口错误;(2) upstream timed out——增加 proxy_read_timeout;(3) 502 Bad Gateway——后端崩溃或返回无效响应。临时添加 "error_log /var/log/nginx/error.log debug;" 进行详细日志记录。
如何配置 Nginx 对后端使用 HTTP/2?
Nginx 的代理模块只支持上游连接的 HTTP/1.1(截至 2026 年)。HTTP/2 只适用于客户端到 Nginx 的连接(listen 443 ssl http2)。要实现端到端 HTTP/2,对 gRPC 后端使用 grpc_pass 而不是 proxy_pass,或使用支持 HTTP/2 上游的 Nginx Plus。