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;

修复思路:设置合理的 resolvervalid,避免过度缓存。

练习#

  1. 使用加权轮询将 80% 请求分配到 10.0.0.1,20% 分配到 10.0.0.2,并用 curl 验证分布。
  2. 将算法切换为 least_conn,模拟长连接(curl -Nwrk -H)观察连接分配变化。
  3. 通过 hash $request_uri consistent; 观察同一 URI 是否固定到同一后端。