Nginx 学习笔记:负载均衡配置教程,从基础算法到企业级动态方案

0 阅读3分钟

什么是负载均衡?

负载均衡(Load Balancing) 就是把请求分发给多台后端服务器处理,避免单台服务器压力过大。

  • 高可用:某台后端挂了,请求自动转发到其他服务器
  • 高并发:多台服务器一起扛流量
  • 易扩展:流量大了加服务器就行

基本使用:proxy_pass

最简单的写法,直接在 proxy_pass 填后端地址:

server {
    listen 80;
    location / {
        proxy_pass http://192.168.1.10:8080;
    }
}

但这种方式不支持故障转移,仅适合开发测试。

生产配置:upstream 块

把后端服务器定义在 upstream 块中,server 块引用它。upstreamserver 同级,都放在 http 里:

http {
    upstream blog_servers {
        server 192.168.1.10:8080;
        server 192.168.1.11:8080;
        server 192.168.1.12:8080;
    }

    server {
        listen 80;
        server_name blog.example.com;

        location / {
            proxy_pass http://blog_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;
        }
    }
}

六大负载均衡算法

默认是轮询,可以通过配置切换到其他算法。

1. 轮询(Round Robin)

请求按顺序轮流分发到每台后端。什么都不配就是轮询

upstream backend {
    server 192.168.1.10:8080;
    server 192.168.1.11:8080;
    server 192.168.1.12:8080;
}

适用:后端配置相同、处理时间相近的场景。不适用:后端性能差异大或响应时间波动大的场景。

2. 权重(Weight)

weight 控制请求比例,数字越大分到的越多:

upstream backend {
    server 192.168.1.10:8080 weight=3;
    server 192.168.1.11:8080 weight=2;
    server 192.168.1.12:8080 weight=1;
}

两个辅助参数:

  • down:标记下线,运维维护时用
  • backup:备用节点,主节点全挂了才启用
upstream backend {
    server 192.168.1.10:8080 weight=3;
    server 192.168.1.11:8080 weight=2;
    server 192.168.1.12:8080 backup;
    server 192.168.1.13:8080 down;
}

3. IP Hash(ip_hash)

同一个客户端 IP 始终转发到同一台后端。解决 Session 保持问题——如果应用把用户会话存在本地内存,请求跳到别的服务器会话就丢了。

upstream backend {
    ip_hash;
    server 192.168.1.10:8080;
    server 192.168.1.11:8080;
    server 192.168.1.12:8080;
}

注意:NAT 环境下多用户共享同一出口 IP,会导致负载不均;某台后端宕机时,它上面的用户会话会全部丢失。

4. Least Connections(least_conn)

转发给当前活跃连接数最少的服务器:

upstream backend {
    least_conn;
    server 192.168.1.10:8080;
    server 192.168.1.11:8080;
    server 192.168.1.12:8080;
}

适用:长连接场景(WebSocket、gRPC),避免连接堆积。注意:连接数少不代表负载轻。

5. URL Hash

根据请求的 URL 做 Hash,相同 URL 始终转发到同一台后端,适合做缓存亲和

upstream backend {
    hash $request_uri;
    server 192.168.1.10:8080;
    server 192.168.1.11:8080;
    server 192.168.1.12:8080;
}

适用:CDN 回源、资源类请求。注意:增减节点会导致 URL 重新映射,缓存可能大面积失效。

6. Fair(第三方模块)

根据后端响应时间分发,响应快的分到更多请求。需额外安装 ngx_http_upstream_fair_module

upstream backend {
    fair;
    server 192.168.1.10:8080;
    server 192.168.1.11:8080;
    server 192.168.1.12:8080;
}

注意:该模块多年未更新,不兼容 Nginx 1.17+,不推荐在生产环境使用。

常见配置参数

故障转移

upstream backend {
    server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;
    server 192.168.1.11:8080 max_fails=3 fail_timeout=30s;
}
  • max_fails=3:30 秒内失败 3 次,标记为不可用
  • fail_timeout=30s:标记不可用后,等待 30 秒再尝试恢复

proxy_next_upstream

遇到后端报错时自动切换到下一台:

location / {
    proxy_pass http://backend;
    proxy_next_upstream error timeout http_500 http_502 http_503;
    proxy_next_upstream_tries 2;
}

企业级方案(思路)

上面讲的算法都是静态配置——后端变了就得改配置文件然后 reload。在微服务或容器环境下(后端频繁扩缩容),这种方式不现实。

生产环境的思路是:

  • OpenResty + Lua 脚本:通过 balancer_by_lua_block 在运行时动态选择后端,配合健康检查自动摘除故障节点,新增节点也不需要 reload
  • nginx-upsync-module + Consul:从 Consul 拉取后端列表,自动更新 upstream
  • Nginx Plus 商业版:内置动态 upstream 管理 API 和主动健康检查,花钱省事

这些方案需要 Lua 或服务注册发现的知识,属于进阶内容,这里只提概念不展开。

总结

算法配置指令适用场景
轮询默认后端配置相同,请求处理时间相近
权重weight服务器配置不同,按能力分配
IP Haship_hash需 Session 保持
Least Connectionsleast_conn长连接、WebSocket
URL Hashhash $request_uri缓存亲和、CDN 回源
Fairfair(第三方)⚠️ 不推荐生产使用

快速自检

  • ✅ 能写出 upstream + proxy_pass 的基础配置
  • ✅ 知道六种算法的配置指令和各自适用场景
  • ✅ 知道 max_failsfail_timeout 的用法
  • ✅ 知道 proxy_next_upstream 做故障转移
  • ✅ 知道内置算法都是静态配置,企业场景需要动态方案