7.3.2 upstream与负载均衡算法
本节聚焦 Nginx 的 upstream 机制与常见负载均衡算法,通过原理图、可执行配置、验证命令与排错步骤,帮助在反向代理场景中实现流量分发、容错与资源利用最大化。
upstream 组件与基本语法#
upstream 用于定义后端服务器池,是负载均衡的核心。典型结构包括名称、服务器列表、权重及状态参数。
原理草图(请求分发)#
基本配置示例(完整可运行)#
文件:/etc/nginx/conf.d/upstream.conf
upstream backend {
server 10.0.0.1:8080 weight=3 max_fails=2 fail_timeout=10s;
server 10.0.0.2:8080 weight=1 max_fails=2 fail_timeout=10s;
server 10.0.0.3:8080 backup;
}
server {
listen 80;
server_name app.example.com;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
关键参数解释#
weight:权重,决定请求分配比例max_fails/fail_timeout:失败次数与时间窗口backup:备份节点,仅在主节点不可用时启用down:手动下线节点
负载均衡算法类型#
Nginx 内置多种算法,可根据业务特征选择。
1. 轮询(round robin,默认)#
- 按顺序分配请求,支持
weight - 适合大多数无状态服务
upstream backend {
server 10.0.0.1:8080 weight=3;
server 10.0.0.2:8080 weight=1;
}
2. IP Hash#
- 基于客户端 IP 计算哈希,实现会话粘性
- 后端变更会导致哈希抖动,可能负载不均
upstream backend {
ip_hash;
server 10.0.0.1:8080;
server 10.0.0.2:8080;
}
3. least_conn(最少连接数)#
- 分配到当前连接数最少的后端
- 适合长连接/慢请求场景
upstream backend {
least_conn;
server 10.0.0.1:8080;
server 10.0.0.2:8080;
}
4. hash(自定义哈希)#
- 基于 URI、请求头等变量计算哈希
- 一致性哈希适合缓存命中优化
upstream backend {
hash $request_uri consistent;
server 10.0.0.1:8080;
server 10.0.0.2:8080;
}
安装与启用(验证环境)#
适用于首次搭建测试环境的快速验证。
# 安装 Nginx
sudo yum install -y nginx || sudo apt-get install -y nginx
# 检查配置语法
sudo nginx -t
# 启动并设为开机自启
sudo systemctl enable --now nginx
# 查看监听端口
ss -lntp | grep nginx
预期效果:nginx -t 输出 syntax is ok,80 端口监听正常。
负载均衡效果验证与观察#
1. 简单验证请求分配#
在后端启动简易服务(示例为 Python):
# 在 10.0.0.1 上
python3 -m http.server 8080 --bind 0.0.0.0
# 在 10.0.0.2 上
python3 -m http.server 8080 --bind 0.0.0.0
客户端访问并观察响应:
for i in {1..6}; do curl -s http://app.example.com | head -n1; done
预期效果:轮询模式下两台后端交替返回。
2. 访问日志观察分配比例#
# 统计后端访问分布
awk '{print $7}' /var/log/nginx/access.log | grep -E '10\.0\.0\.[12]' | sort | uniq -c
3. 压测验证算法差异#
# 100 并发,1 万请求
wrk -c 100 -t 4 -d 30s http://app.example.com/
常见问题与排错#
1. 后端不通导致 502#
# 检查后端端口连通性
curl -v http://10.0.0.1:8080/
curl -v http://10.0.0.2:8080/
修复思路:检查后端服务是否启动、防火墙、SELinux 或安全组。
2. 负载不均或热点#
# 检查是否使用了 ip_hash 或权重设置过大
grep -R "ip_hash\|weight" /etc/nginx/conf.d/
修复思路:降低权重差异,避免 NAT 场景下 IP hash。
3. DNS 解析未更新(动态域名)#
resolver 114.114.114.114 valid=10s;
修复思路:设置合理的 resolver 与 valid,避免过度缓存。
练习#
- 使用加权轮询将 80% 请求分配到 10.0.0.1,20% 分配到 10.0.0.2,并用
curl验证分布。 - 将算法切换为
least_conn,模拟长连接(curl -N或wrk -H)观察连接分配变化。 - 通过
hash $request_uri consistent;观察同一 URI 是否固定到同一后端。