Nginx 全面解析:负载均衡与反向代理机制
反向代理服务在现代Web架构中扮演着关键角色,其核心功能之一是缓存资源,从而显著提升网站响应速度和访问效率。部署时,反向代理服务器通常位于Web服务器之前,负责接收客户端请求,将静态内容进行缓存,并将动态请求依据负载均衡策略分发至后端多个Web服务器实例。
处理完成的响应数据会再次通过反向代理返回给用户。由于Web服务器不直接暴露于公网,因此无需配置公网IP地址;而反向代理服务器则需具备内外双网卡结构,分别配置内部网络和外部网络的IP地址,以实现流量的统一入口与转发控制。
主流 Nginx 变体版本概述
官方版(Nginx Official)
由 Nginx 官方团队维护的标准发行版本,专注于提供稳定、高效的核心功能。该版本定期更新,包含安全补丁与性能优化,适用于绝大多数应用场景,是企业及个人开发者广泛采用的基础选择。
Nginx Plus
作为官方推出的商业增强版本,Nginx Plus 提供了诸如会话保持(Sticky Sessions)、应用层负载均衡、动态DNS解析、实时健康检测以及高级监控管理等特性。适合对稳定性、可管理性和技术支持有更高要求的企业级部署环境。
OpenResty
基于 Nginx 深度扩展的高性能 Web 平台,集成了 LuaJIT 引擎和丰富的 Lua 模块库,允许开发者使用 Lua 语言编写复杂的业务逻辑和自定义模块。适用于需要高并发处理能力及动态内容生成的场景,如API网关、实时服务等。
Tengine
由阿里巴巴主导开发并持续维护的 Nginx 分支版本,专为大规模互联网应用优化。在原始 Nginx 功能基础上增加了动态模块加载、更优的请求处理机制及多项性能调优特性,广泛应用于国内大型互联网企业的生产环境中。
基于 Nginx 的负载均衡实践案例
本实验通过配置 Nginx 实现对 Web 集群的反向代理与负载均衡,验证其在多服务器环境下的请求分发能力。
实验准备条件
- 关闭 SELinux 安全策略
- 禁用系统防火墙或配置相应规则放行流量
网络拓扑结构
主机规划信息
| 主机名 | IP 地址 | 服务器角色 |
|---|---|---|
| client2.shizhan.cloud | 10.1.1.21 | 客户端 |
| client1.shizhan.cloud | 10.1.8.21 | 客户端 |
| router.shizhan.cloud | 10.1.1.20, 10.1.8.20 | 路由器 |
| nginx.shizhan.cloud | 10.1.1.10, 10.1.8.10 | 代理服务器 |
| web1.shizhan.cloud | 10.1.8.11 | Web 服务器 |
| web2.shizhan.cloud | 10.1.8.12 | Web 服务器 |
| web3.shizhan.cloud | 10.1.8.13 | Web 服务器 |
网络配置说明
- 所有主机均配备两块网卡:ens33(默认 NAT 模式)和 ens192(Host-Only 模式)
- ens33 网卡用于连接外部网络,ens192 用于内部通信
- 子网网关设置如下:
- 10.1.1.0/24 网段的网关为 10.1.1.20
- 10.1.8.0/24 网段的网关为 10.1.8.20
基础网络配置命令参考
# 设置 10.1.1.0/24 网段的默认网关 nmcli connection modify ens33 ipv4.gateway 10.1.1.20 nmcli connection up ens33 # 设置 10.1.8.0/24 网段的默认网关 nmcli connection modify ens33 ipv4.gateway 10.1.8.20 nmcli connection up ens33
Router 节点配置步骤
# 启用 Linux 内核的 IP 转发功能 echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf sysctl -p # 或使用 sed 命令直接替换原配置项 # sed -i "s/ip_forward=0/ip_forward=1/g" /etc/sysctl.conf # 启动并启用防火墙服务 systemctl enable firewalld.service --now # 开启地址伪装(MASQUERADE),实现跨网段路由转发 firewall-cmd --add-masquerade firewall-cmd --add-masquerade --permanent
Web 服务器集群部署流程
[root@web1-3 ~]# # 安装 Nginx 服务 yum install -y nginx # 创建测试首页内容,显示当前主机名 echo Welcome to $(hostname) > /usr/share/nginx/html/index.html # 启动并设置开机自启 systemctl enable nginx.service --now
后端服务连通性验证
# 从 client1 访问各 Web 节点 [root@client1 ~]# curl 10.1.8.11 Welcome to web1.shizhan.cloud [root@client1 ~]# curl 10.1.8.12 Welcome to web2.shizhan.cloud
访问测试结果如下:
[root@client1 ~]# curl 10.1.8.13 Welcome to web3.shizhan.cloud
在客户端 client1 上进行多次请求验证:
[root@client1 ~]# echo "10.1.8.10 www.shizhan.cloud www" >> /etc/hosts
[root@client1 ~]# for i in {1..90};do curl -s www.shizhan.cloud;done|sort|uniq -c
30 Welcome to web1.shizhan.cloud
30 Welcome to web2.shizhan.cloud
30 Welcome to web3.shizhan.cloud
同样地,在 client2 上也执行相同的访问测试:
[root@client2 ~]# echo "10.1.8.10 www.shizhan.cloud www" >> /etc/hosts
[root@client2 ~]# for i in {1..90};do curl -s www.shizhan.cloud;done|sort|uniq -c
30 Welcome to web1.shizhan.cloud
30 Welcome to web2.shizhan.cloud
30 Welcome to web3.shizhan.cloud
结论:后端服务器以轮询方式处理来自客户端的请求,实现了基本的负载均衡效果。
Nginx 负载均衡机制配置说明
通过 Nginx 的 upstream 模块可以定义一组后端服务器,供 proxy_pass 或 fastcgi_pass 引用。这些服务器可监听不同端口,也可使用 Unix Socket 形式通信。同时支持设置权重、故障重试策略,并可根据运维需求标记为不可用或备用状态。
安装并配置 Nginx 服务:
[root@nginx ~]# yum install -y nginx
将默认配置文件复制为自定义代理配置:
[root@nginx ~]# cp /etc/nginx/nginx.conf /etc/nginx/conf.d/proxy.conf [root@nginx ~]# vim /etc/nginx/conf.d/proxy.conf
编辑后的配置内容示例如下:
upstream web {
server 10.1.8.11:80;
server 10.1.8.12:80;
server 10.1.8.13:80;
}
server {
server_name www.shizhan.cloud;
root /usr/share/nginx/html;
location / {
proxy_pass http://web;
}
}
启动 Nginx 服务以应用配置:
[root@nginx ~]# systemctl start nginx.service
upstream 指令详解
upstream 模块中常用指令包括:
- keepalive:指定每个 worker 进程为 upstream 服务器保持的空闲连接数量。
- server:定义一个后端服务器地址,可附加多种参数控制行为。
常见 server 参数说明:
- weight:设置服务器权重,默认为1,值越大转发越多。
- max_fails:允许的最大失败请求数,结合 fail_timeout 使用。
- fail_timeout:设定超时时间,在此期间内若请求失败次数超过 max_fails,则视为节点不可用。
- backup:标记为备份服务器,仅当所有主服务器失效时才启用。
- down:手动禁用该服务器,不参与负载分配。
示例配置:
upstream web {
keepalive 32;
server 10.1.8.11:80 max_fails=3 fail_timeout=30s weight=2;
server 10.1.8.12:80 max_fails=3 fail_timeout=30s backup;
server 10.1.8.13:80 max_fails=3 fail_timeout=30s down;
}
调度算法分类
Nginx 的 upstream 模块支持多种调度算法,主要分为两类:
静态调度算法:由负载均衡器根据预设规则进行分发,不依赖后端服务器实时状态。典型代表包括:
- rr(Round Robin,轮询)
- ip_hash(基于客户端 IP 的哈希分配)
动态调度算法:根据后端节点的实时响应情况(如连接数、响应时间等)动态调整流量分配,适用于对性能敏感的场景。
upstream name {
....
}通用哈希(generic Hash)是一种灵活的负载均衡调度方式,其核心机制是根据用户自定义的键值进行哈希计算,从而决定请求应转发至哪一台后端服务器。该键可以是静态文本、Nginx变量,或多个变量的组合,例如客户端的源IP与端口对,或者请求的URI等。
在配置中,通过在upstream块内使用hash指令来启用此策略。需要注意的是,一旦启用hash调度算法,server指令中不能再包含weight等其他参数。默认采用普通hash算法,若需基于URL内容进行哈希分发,可使用hash $request_uri实现类似url_hash的效果,使得相同URL的请求始终指向同一台后端节点,有助于提升缓存命中率和系统整体性能。
值得注意的是,Nginx官方版本并不原生支持url_hash功能,如需使用此类特性,必须手动编译并安装第三方hash模块。
示例配置如下:
upstream web {
hash $request_uri;
server 10.1.8.11:80;
server 10.1.8.12:80;
server 10.1.8.13:80;
}
执行前需确保相关目录已创建:
[root@web1-3 ~]# mkdir /usr/share/nginx/html/test
轮询(round-robin)为Nginx默认的负载均衡算法。它按照配置顺序依次将客户端请求分发到各个后端服务器上,实现基本的流量均摊。当某台后端服务器出现故障(通常指80端口无法响应),Nginx会自动将其从服务池中剔除,后续请求将仅由正常运行的节点处理,从而保障用户体验不受影响。
示例配置:
upstream web {
server 10.1.8.11:80;
server 10.1.8.12:80;
server 10.1.8.13:80;
}
测试命令及结果:
[root@client1 ~]# for n in {1..90}; do curl http://10.1.8.10 -s; done | sort |uniq -c
30 Welcome to web1.shizhan.cloud
30 Welcome to web2.shizhan.cloud
30 Welcome to web3.shizhan.cloud
upstream name {
....
}
在基础轮询的基础上,可以通过添加权重(weight)参数优化请求分配逻辑。权重值反映服务器的处理能力,数值越大,接收的请求越多。这种机制特别适用于异构服务器环境,能够有效平衡高性能与低性能设备之间的负载差异。
配置示例如下:
upstream web {
server 10.1.8.11:80 weight=10;
server 10.1.8.12:80 weight=20;
server 10.1.8.13:80 weight=30;
}
对应的测试输出显示了按比例分配的结果:
[root@client1 ~]# for n in {1..90}; do curl http://10.1.8.10 -s; done | sort |uniq -c
15 Welcome to web1.shizhan.cloud
30 Welcome to web2.shizhan.cloud
45 Welcome to web3.shizhan.cloud
least_time
IP哈希(ip_hash)调度算法依据客户端IP地址的哈希值进行请求分配。每当新请求到达时,系统会对客户端IP执行哈希运算,确保来自同一IP的请求始终被定向到相同的后端服务器。这一机制常用于解决动态网页应用中的session会话保持问题。
然而,在实际网络环境中,尤其是在国内普遍采用NAT上网模式的情况下,多个用户可能共享同一个公网IP,导致大量请求集中于单一后端节点,造成负载不均现象。
此外,LVS中的-p参数、Keepalived配置中的persistence_timeout 50等设置,功能上均与Nginx的ip_hash类似,均可实现会话保持效果。
配置示例:
upstream web {
ip_hash;
server 10.1.8.11:80;
server 10.1.8.12:80;
server 10.1.8.13:80;
}
测试结果如下:
[root@client1 ~]# for n in {1..90}; do curl http://10.1.8.10 -s; done | sort |uniq -c
90 Welcome to web3.shizhan.cloud
[root@client2 ~]# for n in {1..90}; do curl http://10.1.8.10 -s; done | sort |uniq -c
90 Welcome to web2.shizhan.cloud
header
动态感知型调度策略是指负载均衡器能够实时监测后端节点的状态,并据此调整请求分发逻辑。例如,选择当前连接数较少的服务器(least_conn)或响应时间最短的服务器(least_time)优先处理新请求,从而实现更精细化的负载控制和资源利用效率提升。
配置 Web 服务器 [root@web1-3 ~]# # 部署 Web 服务 yum install -y httpd echo Welcome to shizhan.Web3 WebSite! > /var/www/html/index.html systemctl enable httpd.service --now # 客户端访问后端验证 [root@client ~ 16:07:33]# curl web1 Welcome to shizhan.Web1 WebSite! [root@client ~ 16:09:44]# curl web3 Welcome to shizhan.Web3 WebSite! [root@client ~ 16:09:46]# curl web2 Welcome to shizhan.Web2 WebSite!
网络拓扑信息
| 主机名 | IP地址 | 服务器角色 |
|---|---|---|
| client.shizhan.cloud | 10.1.8.10 | 客户端 |
| web1.shizhan.cloud | 10.1.8.11 | Web 服务器 |
| web2.shizhan.cloud | 10.1.8.12 | Web 服务器 |
| web3.shizhan.cloud | 10.1.8.13 | Web 服务器 |
| web.shizhan.cloud | 10.1.8.100 | 代理服务器 |
Nginx 代理配置 # 安装 Nginx [root@nginx ~]# yum install -y nginx # 备份并创建新的配置文件 [root@nginx ~]# cp /etc/nginx/nginx.conf /etc/nginx/conf.d/proxy.conf [root@nginx ~]# vim /etc/nginx/conf.d/proxy.conf
后端服务器分组配置
upstream web {
server web1:80 weight=10;
server web2:80 weight=20;
server web3:80 weight=30;
}
前端监听配置
server {
server_name web.shizhan.cloud;
location / {
proxy_pass http://web;
}
}
# 启动 Nginx 服务 [root@nginx ~]# systemctl start nginx.service
轮询策略测试结果
[root@client ~ 16:20:38]# for i in {1..90}; do curl -s http://web;done | sort | uniq -c
30 Welcome to shizhan.Web1 WebSite!
30 Welcome to shizhan.Web2 WebSite!
30 Welcome to shizhan.Web3 WebSite!
最少连接数负载均衡(least_conn)
该策略会将请求分配给当前活跃连接数最少的后端服务器,从而实现更均衡的负载分发。
示例配置:
upstream web {
least_conn;
server 10.1.8.11:80;
server 10.1.8.12:80;
server 10.1.8.13:80;
}
测试输出
[root@client1 ~]# for n in {1..90}; do curl http://10.1.8.10 -s; done | sort |uniq -c
30 Welcome to web1.shizhan.cloud
30 Welcome to web2.shizhan.cloud
30 Welcome to web3.shizhan.cloud
提示:least_conn 策略支持设置权重,结合 weight 参数可进一步优化流量分配。
最少时间负载算法(Least Time)
注意:此算法仅在 NGINX Plus 商业版本中提供,开源版 Nginx 不支持。
NGINX Plus 根据以下两个指标选择最优服务器:
- 最低平均响应延迟
- 最少的活跃连接数
其中,平均延迟依据如下参数计算:
least_time
– 接收第一个字节的时间(header)
header
– 接收完整响应的时间(last_byte)
last_byte
– 考虑不完整请求情况下的完整响应时间(last_byte inflight)
last_byte inflight
配置示例:
upstream web {
least_time header;
server 10.1.8.11:80;
server 10.1.8.12:80;
server 10.1.8.13:80;
}
初始测试命令与输出
[root@web1-3 ~]# echo test from $(hostname -s) > /usr/share/nginx/html/test/index.html
测试结果
[root@client1 ~]# for n in {1..90}; do curl http://10.1.8.10 -s; done | sort |uniq -c
90 Welcome to web3.shizhan.cloud
配置Nginx负载均衡中的备用服务器
在Nginx的反向代理设置中,可以通过定义upstream块来实现后端服务器的负载均衡。其中,可以指定某台主机作为备用机(backup),仅当所有其他主服务器不可用时才会被启用。
upstream web {
server web1:80 weight=10;
# web2设为备用服务器
server web2:80 weight=20 backup;
server web3:80 weight=30;
}
server {
server_name web.shizhan.cloud;
location / {
proxy_pass http://web;
}
}
测试验证场景
场景一:正常情况下请求分配情况
当web1和web3的httpd服务均处于运行状态时,由于web2被标记为backup,因此不会接收任何客户端请求。
[root@client ~ 17:13:43]# for i in {1..40}; do curl -s http://web;done | sort | uniq -c
10 Welcome to shizhan.Web1 WebSite!
30 Welcome to shizhan.Web3 WebSite!
结果显示请求只分发到了web1和web3,符合预期。
场景二:关闭web3服务后的请求分配
停止web3上的httpd服务后,所有流量将由web1接管。
[root@web3 ~ 17:12:38]# systemctl stop httpd.service
[root@client ~ 17:13:44]# for i in {1..40}; do curl -s http://web;done | sort | uniq -c
40 Welcome to shizhan.Web1 WebSite!
此时web3已失效,但由于web1仍在运行,故未触发对web2的调用。
场景三:web1与web3均宕机时的故障转移
当web1和web3的服务都停止后,系统自动切换至备用机web2。
[root@client ~ 17:15:29]# for i in {1..40}; do curl -s http://web;done | sort | uniq -c
40 Welcome to shizhan.Web2 WebSite!
upstream name {
....
}
手动停用特定服务器(down参数)
通过在配置中使用down指令,可临时禁用某个服务器节点,无论其实际服务是否正在运行,Nginx都不会向其转发请求。
upstream web {
server web1:80 weight=10;
server web2:80 weight=20 backup;
# web3被标记为已下线
server web3:80 weight=30 down;
}
server {
server_name web.shizhan.cloud;
location / {
proxy_pass http://web;
}
}
重启Nginx以应用更改:
[root@web conf.d 17:19:50]# systemctl restart nginx
尽管此时web1、web2、web3的httpd服务均已启动,但因web3被设为down,客户端请求不会被发送至该主机。
[root@client ~ 17:16:49]# for i in {1..90}; do curl -s http://web;done | sort | uniq -c
90 Welcome to shizhan.Web1 WebSite!
结果表明,所有请求均由web1处理,进一步验证了down指令的有效性。


雷达卡


京公网安备 11010802022788号







