Nginx 负载均衡实战指南:从原理到生产级配置
文章目录
一、概述: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_pass 和 fastcgi_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 负载均衡的底层原理与灵活配置能力,是每一位后端工程师和运维工程师构建高可用、高性能分布式系统的必备技能。希望本文能为读者的架构设计与生产实践提供切实可行的参考。
更多推荐
所有评论(0)