一、概述:Nginx 反向代理与七层负载均衡

Nginx 作为一款高性能的 HTTP 和反向代理服务器,不仅支持 七层 HTTP/HTTPS 代理,还具备 四层 TCP/UDP 代理 能力。通过 Nginx 反向代理实现负载均衡,是互联网架构中最为经典且广泛采用的流量分发方案。

本文将以实战为导向,系统梳理 Nginx 负载均衡的核心配置、Upstream 模块指令、六大调度算法的原理与适用场景,并辅以完整的配置示例与测试验证,帮助读者建立从理论到生产部署的完整知识链路。


二、代理服务器配置实战

1. 基础配置

以下为一个典型的 Nginx 反向代理负载均衡配置示例:

# 配置nginx
[root@proxy ~]# vim /etc/nginx/conf.d/proxy.conf
server {
    listen  80;
    server_name www.laogao.cloud;
    location / {
        proxy_pass http://backends/;
    }
}

upstream backends {
    server nginx1.laogao.cloud:80;
    server nginx2.laogao.cloud:80;
    server nginx3.laogao.cloud:80;
}

2. 服务重启与防火墙放行

# 启动并启用服务
[root@proxy ~]# nginx -s reload

# 防火墙设置
[root@proxy ~]# firewall-cmd --add-service=http --permanent
[root@proxy ~]# firewall-cmd --add-service=http

3. 负载均衡验证

通过循环请求验证负载均衡效果:

[root@client ~]# for n in {1..90}; do curl http://www.laogao.cloud -s; done | sort | uniq -c
30 Welcome to nginx1.laogao.cloud
30 Welcome to nginx2.laogao.cloud
30 Welcome to nginx3.laogao.cloud

可以看到,90 次请求被均匀分配到了三台后端服务器,每台各承接 30 次,负载均衡效果显著。


三、Upstream 模块详解

Nginx 的 upstream 模块用于声明一组可以被 proxy_passfastcgi_pass 引用的后端服务器。这些服务器既可以使用不同的端口,也可以基于 Unix Socket 通信。更重要的是,每台后端服务器可被赋予不同的权重、连接数限制、故障恢复策略等精细化的控制参数。

1. 基础语法

upstream name {
    ...
}

2. 配置示例

upstream backend {
    server backend1.example.com weight=5 down backup;
    server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
    server unix:/tmp/backend2;
}

3. 常用指令一览

指令说明
keepalive每个 worker 进程为发送到 upstream 服务器的连接所缓存的个数
server定义一个 upstream 服务器的地址,还可包括一系列可选参数
weight权重,默认值为 1;权重越大,被转发的请求越多
max_fails最大失败连接次数,失败连接的超时时长由 fail_timeout 指定
fail_timeout等待请求的目标服务器发送响应的时长
backup备用服务器,仅当所有主服务器均故障时才启用
down手动标记该服务器不再处理任何请求

4. 综合配置示例

upstream backends {
    keepalive 32;
    server nginx1.laogao.cloud:80 max_fails=3 fail_timeout=30s;
    server nginx2.laogao.cloud:80 max_fails=3 fail_timeout=30s weight=2;
    server nginx3.laogao.cloud:80 max_fails=3 fail_timeout=30s backup;
    server nginx4.laogao.cloud:80 max_fails=3 fail_timeout=30s down;
}

四、负载均衡调度算法

Nginx 的 upstream 模块调度算法一般分为 静态调度算法动态调度算法 两大类:

  • 静态调度算法:负载均衡器根据自身预设的规则进行分配,无需感知后端节点服务器的实时状态。例如轮询(rr)、IP Hash 等。
  • 动态调度算法:负载均衡器根据后端节点的当前运行状态(如连接数、响应延迟等)动态决策请求分发目标。例如最少连接(least_conn)、最少时间(least_time)等。

下面逐一介绍 Nginx 支持的六种核心调度算法。

1. 轮询(Round-Robin)

Nginx 默认的调度算法。 按客户端请求的到达顺序,依次将请求分配到不同的后端节点服务器。如果某台后端服务器宕机(Nginx 默认检测 80 端口),该服务器会被自动从节点池中剔除,后续请求将不再分发至该节点,从而实现故障自动转移。

配置示例:

[root@proxy ~]# vim /etc/nginx/conf.d/proxy.conf
upstream backends {
    server nginx1.laogao.cloud:80;
    server nginx2.laogao.cloud:80;
    server nginx3.laogao.cloud:80;
}

测试结果:

[root@client ~]# for i in {1..60}; do curl http://www.laogao.cloud -s; done | sort | uniq -c
20 Welcome to nginx1.laogao.cloud
20 Welcome to nginx2.laogao.cloud
20 Welcome to nginx3.laogao.cloud

60 次请求被平均分配到三台服务器,每台各 20 次,完美轮询。

2. 权重(Weight)

在轮询算法的基础上,可以为每台后端服务器指定权重值。权重与流量分配成正比——权重越高,被转发的请求越多。这一特性非常适合解决新旧服务器性能不均时的流量分配问题。

配置示例:

[root@proxy ~]# vim /etc/nginx/conf.d/proxy.conf
upstream backends {
    server nginx1.laogao.cloud:80 weight=10;
    server nginx2.laogao.cloud:80 weight=20;
    server nginx3.laogao.cloud:80 weight=30;
}
[root@proxy ~]# nginx -s reload

测试结果:

[root@client ~]# for i in {1..60}; do curl http://www.laogao.cloud -s; done | sort | uniq -c
10 Welcome to nginx1.laogao.cloud
20 Welcome to nginx2.laogao.cloud
30 Welcome to nginx3.laogao.cloud

请求按照 10:20:30 的比例精确分配,权重策略生效。

3. IP 哈希(IP Hash)

每个请求根据客户端 IP 的哈希结果进行分配。当新请求到达时,Nginx 通过哈希算法对客户端 IP 计算出一个固定值,在后续请求中,只要客户端 IP 不变,就会被始终路由到同一台后端服务器。

优势:可有效解决动态网页的 Session 共享问题。

局限性:在国内多数企业采用 NAT 上网的场景下,多个客户端共享同一个外部 IP,导致这些客户端被统一路由到同一台后端服务器,造成请求分配不均。此外,该模式不支持 backup 节点。

LVS 负载均衡的 -p 参数、Keepalived 配置中的 persistence_timeout 50 参数,其原理与 Nginx 的 ip_hash 类似。

配置示例:

[root@proxy ~]# vim /etc/nginx/conf.d/proxy.conf
upstream backends {
    ip_hash;
    server nginx1.laogao.cloud:80;
    server nginx2.laogao.cloud:80;
    server nginx3.laogao.cloud:80;
}
[root@proxy ~]# nginx -s reload

测试结果:

[root@client ~]# for i in {1..60}; do curl http://www.laogao.cloud -s; done | sort | uniq -c
60 Welcome to nginx2.laogao.cloud

所有请求均被路由到同一台服务器(基于客户端 IP 哈希一致性)。

4. 通用哈希(Generic Hash)

请求路由的目标服务器由用户自定义的键(Key)决定,该键可以是文本字符串、变量或它们的组合。例如,键可以是源 IP 地址与端口的配对,也可以是 URI。

注意:在 upstream 中使用 hash 指令后,nginx 语句中不能再写入 weight 等其他参数。hash_method 指定所使用的哈希算法。

url_hash 按访问 URL 的哈希结果分配请求,使同一 URL 始终定向到同一台后端服务器,可进一步提升后端缓存的命中率。但 Nginx 开源版不原生支持 url_hash,需额外安装 hash 模块。

配置示例:

[root@proxy ~]# vim /etc/nginx/conf.d/proxy.conf
upstream backends {
    hash $request_uri;
    # hash_method crc32;
    server nginx1.laogao.cloud:80;
    server nginx2.laogao.cloud:80;
    server nginx3.laogao.cloud:80;
}
[root@proxy ~]# nginx -s reload

测试结果:

[root@client ~]# for i in {1..60}; do curl http://www.laogao.cloud -s; done | sort | uniq -c
60 Welcome to nginx3.laogao.cloud

5. 最少连接数(Least Connections)

将新请求分发到当前活跃连接数最少的后端服务器。该算法特别适合后端节点处理请求耗时差异较大的场景,能够有效避免连接数多的服务器继续堆积请求。

配置示例:

[root@proxy ~]# vim /etc/nginx/conf.d/proxy.conf
upstream backends {
    least_conn;
    server nginx1.laogao.cloud:80;
    server nginx2.laogao.cloud:80;
    server nginx3.laogao.cloud:80;
}
[root@proxy ~]# nginx -s reload

测试结果:

[root@client ~]# for i in {1..60}; do curl http://www.laogao.cloud -s; done | sort | uniq -c
20 Welcome to nginx1.laogao.cloud
20 Welcome to nginx2.laogao.cloud
20 Welcome to nginx3.laogao.cloud

最少连接数同样支持 weight 权重参数

6. 最少时间(Least Time)

仅限 Nginx Plus(商业版)

对于每个请求,Nginx Plus 会选择具有最低平均延迟和最少活动连接数的服务器。最低平均延迟由 least_time 指令中的参数计算得出:

  • header:从服务器接收第一个字节的时间
  • last_byte:从服务器接收完整响应的时间
  • last_byte inflight:从服务器接收完整响应的时间,同时考虑未完成的请求

配置示例:

[root@proxy ~]# vim /etc/nginx/conf.d/proxy.conf
upstream backends {
    least_time header;
    server nginx1.laogao.cloud:80;
    server nginx2.laogao.cloud:80;
    server nginx3.laogao.cloud:80;
}
[root@proxy ~]# nginx -s reload

五、调度算法对比总结

算法配置写法核心逻辑使用场景特点
轮询(Round Robin,默认)不写任何策略请求依次分配给后端服务器后端性能差不多,无会话保持需求默认策略,请求逐个轮转;后端故障自动剔除;不做会话绑定
权重(Weight)server x weight=N;按权重比例分配流量后端机器性能不一样,性能好的多承担流量权重越大分到请求越多;权重仅在轮询模式生效;ip_hash 模式 weight 无效
IP 哈希(IP Hash)ip_hash;根据客户端 TCP 源 IP 哈希,同一个 IP 永远落到同一台后端需要会话保持,无前置代理基于 TCP 源 IP,不读取 HTTP 头;前面有 SLB/CDN 会全部打到同一台;不支持 backup 节点
通用哈希(Generic Hash)hash $变量 [consistent];自定义变量做哈希(IP、cookie、header、URL 等)需要基于 cookie/URL 做会话绑定;前置代理环境Nginx 1.7.2+;加 consistent 开启一致性哈希,后端上下线流量抖动变小
最少连接(Least Conn)least_conn;把请求分给当前活跃连接数最少的后端后端处理请求耗时差异大,长连接场景优先找连接数少的机器;weight 权重依然生效
最少时间(Least Time)least_time header;分配给响应时间最短的后端Nginx Plus 商业版,根据历史响应速度调度开源 Nginx 不支持,根据后端历史响应速度择优分配

六、快速记忆口诀

算法口诀
轮询挨个来(默认)
Weight能力强多干活
IP Hash同一个 IP 锁一台后端(TCP 源 IP)
Hash想拿什么就哈希什么(cookie/header/URL),consistent 保稳定
Least Conn谁闲分给谁(看活跃连接)
Least Time谁响应快分给谁(商业版)

七、总结

本文系统性地梳理了 Nginx 负载均衡的完整知识体系,从反向代理的基础配置出发,深入解析了 upstream 模块的核心指令及其参数含义,并逐一演示了六种主流调度算法的配置方法与实战效果。

在实际生产环境中,调度算法的选择并非"越多越好",而是需要根据业务特征进行精准匹配:对于无状态、流量均匀的 API 服务,默认的轮询策略往往已经足够;对于存在性能差异的异构服务器集群,权重策略能够最大化硬件利用率;而对于需要会话保持的 Web 应用,IP Hash 或通用哈希则是更稳妥的选择。此外,对于长连接、高延迟的实时业务场景,最少连接和最少时间等动态调度算法能够显著提升用户体验。

掌握 Nginx 负载均衡的底层原理与灵活配置能力,是每一位后端工程师和运维工程师构建高可用、高性能分布式系统的必备技能。希望本文能为读者的架构设计与生产实践提供切实可行的参考。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐