942 字
5 分钟
Nginx 反向代理与负载均衡配置实战

Nginx 在生产环境最常见的角色不是「Web 服务器」,而是站在所有应用前面的反向代理:对外统一收流量,对内分发给多个后端实例。本文给出一份可以改改就用的配置骨架,并解释每个关键参数为什么存在。

反向代理:最小可用配置#

假设后端应用监听本机 3000 端口,希望通过 80 端口对外提供 HTTP 服务:

server {
listen 80;
server_name example.com;
location / {
proxy_pass http://127.0.0.1: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;
}
}

四行 proxy_set_header 不是装饰,缺了它们后端会丢失关键信息:

  • Host:默认情况下 Nginx 会把请求头改成上游地址,后端基于域名的虚拟主机路由会失效。
  • X-Real-IP / X-Forwarded-For:后端看到的来源 IP 全是 127.0.0.1,日志和限流就废了。X-Forwarded-For 用追加模式,保留完整代理链。
  • X-Forwarded-Proto:告诉后端原始请求是 HTTP 还是 HTTPS,避免应用生成错误的重定向地址。

修改配置后先测试再生效,这是 Nginx 运维的铁律:

Terminal window
nginx -t # 语法检查
systemctl reload nginx # 平滑重载,不断开已有连接

负载均衡:upstream 块#

多个后端实例时,用 upstream 定义服务器组:

upstream app_backend {
# 默认算法:加权轮询
server 10.0.1.11:3000 weight=3;
server 10.0.1.12:3000;
server 10.0.1.13:3000 backup; # 备用节点,前面全挂才启用
# keepalive 32; # 与后端保持的长连接数,减少 TCP 握手
}
server {
listen 80;
location / {
proxy_pass http://app_backend;
# ... 同上 proxy_set_header
}
}

调度算法选择#

算法写法适用场景
加权轮询(默认)server ... weight=N后端无状态、配置不同
最少连接least_conn;请求处理时长差异大(如报表导出)
IP 哈希ip_hash;需要会话粘滞但又没有共享 session 存储

被动健康检查#

开源版 Nginx 没有主动探活,但可以用两个参数实现被动摘除:

server 10.0.1.11:3000 max_fails=3 fail_timeout=30s;

含义:30 秒内连续 3 次连接失败,就把该节点标记为不可用,30 秒后再试探。配合 proxy_next_upstream 可以定义「失败」的范围和重试策略:

proxy_next_upstream error timeout http_502 http_503;
proxy_next_upstream_tries 2;

静态资源与缓存:让后端少干活#

反向代理层顺手做两件事,后端压力能降一个数量级:

# 静态文件直接由 Nginx 返回
location ~* \.(jpg|jpeg|png|css|js|ico|woff2)$ {
root /var/www/app/public;
expires 7d;
add_header Cache-Control "public, immutable";
}
# 开启 gzip
gzip on;
gzip_types text/css application/javascript application/json image/svg+xml;
gzip_min_length 1k;

常见超时参数#

反向代理挂起的连接会拖垮 worker 进程,这组参数值得显式设置:

proxy_connect_timeout 5s; # 与后端建立 TCP 连接的超时
proxy_send_timeout 60s; # 向后端写请求的超时
proxy_read_timeout 60s; # 从后端读响应的超时(慢接口要调大)

如果后端是长轮询或 SSE 接口,proxy_read_timeout 必须大于推送间隔,否则连接会被 Nginx 掐断。

排查入口#

代理出问题时,两个日志位置记牢:

  • error_log(默认 /var/log/nginx/error.log):后端连接失败、上游超时都记在这里。
  • access_log:用自定义格式记录上游耗时,快速定位慢后端:
log_format upstream_log '$remote_addr - $upstream_addr '
'rt=$request_time urt=$upstream_response_time '
'status=$status "$request"';
access_log /var/log/nginx/upstream.log upstream_log;

$request_time 是总耗时,$upstream_response_time 是后端处理耗时——两者差值就是 Nginx 排队和网络开销,一眼看出瓶颈在哪一层。

延伸阅读#

Nginx 反向代理与负载均衡配置实战
https://meow.us.kg/posts/nginx-reverse-proxy-load-balancing/
作者
もゆちゃん
发布于
2026-10-03
许可协议
CC BY-NC-SA 4.0

分享文章

生成精美分享图或复制链接,与更多人分享本文。

继续阅读

沿着主题读

基于共同的标签与分类

换条路线

从其他文章中稳定抽取