开始使用 nginx 的实战负载均衡指南
许多开发者只把 nginx 当作“反向代理 + 静态文件服务器”,但实际上它是一个功能强大的软件负载均衡器。如果你既负责服务器管理,又能熟练使用 nginx,就能在流量高峰时显著提升服务的稳定性和性能。
本文面向初级–中级开发者,将一次性整理以下内容:
- 负载均衡概念
- nginx 负载均衡的配置方法
- 常用算法(round robin、least_conn、ip_hash 等)
- 健康检查(Health Check)
- 常用选项
1. 什么是负载均衡?
负载均衡(load balancing) 简单来说,就是:
“将请求均匀分发到多台服务器,避免单台服务器过载”
为什么需要?
- 防止流量暴涨:即使在高峰期也不让单台服务器宕机。
- 水平扩展(Scale Out):通过增加服务器数量来提升吞吐量,而不是单纯提升硬件规格。
- 高可用性:即使一台服务器失效,流量也能自动切换到其他服务器,保持服务可用。
nginx 在架构中的位置
典型结构如下:
客户端 → nginx(负载均衡器 / 反向代理) → 多台应用服务器
nginx 接收请求后,将其转发到后端的某一台服务器。
2. 理解 nginx 负载均衡的基本结构
nginx 配置中,负载均衡主要由两部分组成:
- upstream 块:定义“后端服务器池”。
- server / location 块:决定哪些请求转发到哪个 upstream。
下面给出最简单的示例。
http {
upstream app_backend {
server 10.0.0.101:3000;
server 10.0.0.102:3000;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://app_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;
}
}
}
这段配置的含义
upstream app_backend:把10.0.0.101:3000与10.0.0.102:3000两台服务器聚合成一个池。proxy_pass http://app_backend;:将客户端请求转发到该池中的一台服务器。- 如果未指定算法,默认使用 round robin。
3. 负载均衡算法类型
nginx 提供多种分发策略,选择合适的算法能显著提升性能。
3.1 基础:Round Robin
默认算法,配置方式:
upstream app_backend {
server 10.0.0.101:3000;
server 10.0.0.102:3000;
}
- 第一次请求 → 服务器1
- 第二次请求 → 服务器2
- 第三次请求 → 再次服务器1 …
优点:实现简单,适用于大多数场景。 缺点:不考虑服务器当前负载。
3.2 least_conn(最少连接)
upstream app_backend {
least_conn;
server 10.0.0.101:3000;
server 10.0.0.102:3000;
}
将新请求路由到当前连接数最少的服务器。适用于请求处理时间差异较大的服务。
推荐场景: * 某些请求耗时长,其他请求很快。 * 服务器规格相近,但请求模式不均衡。
3.3 ip_hash(同一 IP 同一服务器)
upstream app_backend {
ip_hash;
server 10.0.0.101:3000;
server 10.0.0.102:3000;
}
基于客户端 IP 进行哈希,保证同一 IP 的请求始终走同一台服务器,常用于需要粘性会话的场景。
优点:实现简单,适合旧版会话存储在服务器内存的情况。 缺点:服务器增删会导致映射大幅变化;若客户端 IP 通过代理隐藏,效果失效。
3.4 权重(weight)分发
当服务器规格不同时,可通过权重控制流量比例。
upstream app_backend {
server 10.0.0.101:3000 weight=3;
server 10.0.0.102:3000 weight=1;
}
服务器1:服务器2 = 3:1 的请求比例。
4. 健康检查与故障服务器处理
要让负载均衡器真正“聪明”,必须能自动剔除失效服务器。
nginx 开源版默认支持被动健康检查。
4.1 max_fails / fail_timeout
upstream app_backend {
server 10.0.0.101:3000 max_fails=3 fail_timeout=30s;
server 10.0.0.102:3000 max_fails=3 fail_timeout=30s;
}
max_fails=3:连续 3 次失败后将服务器标记为不健康。fail_timeout=30s:在 30 秒内不再向该服务器发送请求,之后再次尝试。
失败判定通常基于 502/503/504 响应或连接失败。
4.2 proxy_next_upstream
决定在何种错误情况下转发到下一台服务器。
location / {
proxy_pass http://app_backend;
proxy_next_upstream error timeout http_502 http_503 http_504;
}
仅在指定错误发生时才重试,避免无谓的延迟。
5. 实战示例:简单 Web 服务负载均衡
假设你有两台 Node.js 服务器,监听 3000 端口:
10.0.0.101:300010.0.0.102:3000
5.1 nginx 配置示例
http {
upstream app_backend {
least_conn;
server 10.0.0.101:3000 max_fails=3 fail_timeout=30s;
server 10.0.0.102:3000 max_fails=3 fail_timeout=30s;
}
server {
listen 80;
server_name myservice.com;
location / {
proxy_pass http://app_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;
proxy_read_timeout 60s;
proxy_connect_timeout 5s;
proxy_send_timeout 10s;
}
}
}
重载 nginx 后:
- 所有请求先到 nginx,再根据最少连接分发到 Node.js 服务器。
- 服务器连续失败时会被自动剔除。
6. HTTPS(SSL)终止 + 负载均衡
生产环境几乎都使用 HTTPS。常见做法是让 nginx 负责 SSL 终止,内部使用 HTTP。
http {
upstream app_backend {
least_conn;
server 10.0.0.101:3000;
server 10.0.0.102:3000;
}
server {
listen 443 ssl;
server_name myservice.com;
ssl_certificate /etc/letsencrypt/live/myservice.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/myservice.com/privkey.pem;
location / {
proxy_pass http://app_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;
}
}
# HTTP → HTTPS 重定向
server {
listen 80;
server_name myservice.com;
return 301 https://$host$request_uri;
}
}
- 客户端与 nginx 之间使用 HTTPS。
- nginx 与后端服务器之间使用 HTTP(内部网络安全即可)。
7. 会话问题:是否需要粘性会话?
过去常见的做法是把会话存放在服务器内存,要求同一用户始终访问同一台服务器。可以用 ip_hash 简单实现,但现代方案更推荐:
- 将会话存放在 Redis 等外部存储。
- 使用 JWT 让应用无状态。
若能在应用层去除状态,负载均衡器只需做流量分发,扩展更友好。
8. 常用调优点
8.1 keepalive
重用后端连接可提升性能。
upstream app_backend {
least_conn;
server 10.0.0.101:3000;
server 10.0.0.102:3000;
keepalive 32;
}
server {
location / {
proxy_pass http://app_backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}
keepalive 32:每个 worker 最多保持 32 条 keepalive 连接。
8.2 缓冲与超时
location / {
proxy_pass http://app_backend;
proxy_buffering on;
proxy_buffers 16 16k;
proxy_busy_buffers_size 64k;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
}
- 超时过短会导致 504 Gateway Timeout。
- 根据实际流量与后端性能调整。
9. nginx 负载均衡的引入策略(分阶段)
如果已有单台服务器运行,建议按以下步骤扩容:
- 第一阶段:将 nginx 作为反向代理引入。 * 客户端 → nginx → 单台应用服务器。 * 处理 SSL、缓存、静态文件等。
- 第二阶段:复制应用服务器,配置 upstream。 * 将两台服务器加入 upstream,开启负载均衡。
- 第三阶段:启用健康检查与监控。
* 配置
max_fails、fail_timeout、proxy_next_upstream。 * 集成 Prometheus + Grafana 或 ELK 进行日志/指标收集。 - 第四阶段:根据流量模式微调算法与参数。
* 选择
least_conn或weight。 * 调整 keepalive、缓冲、超时等。
结语
nginx 的负载均衡功能远不止于“反向代理”。通过合理配置 upstream、算法、健康检查、HTTPS 终止等,你可以轻松提升服务的可用性与性能。掌握这些技巧后,当流量增长时,你就能快速搭建一个更稳健、更可扩展的基础设施。

目前没有评论。