一、引言:为什么需要多种负载均衡策略?
当你的应用从单机走向集群,Nginx 的 upstream 模块就成了流量调度的核心。但"一刀切"的分发方式并不总是最优解。
- 你的服务器硬件配置参差不齐?
- 你的应用需要会话保持(Session Sticky)?
- 你的请求处理时间长短不一?
- 你希望在增减节点时,对现有连接的影响最小?
面对这些不同的场景,Nginx 提供了多种负载均衡策略。选择合适的策略,能让集群资源利用更充分、用户体验更流畅、系统架构更健壮。本文将为你逐一拆解这五大核心策略。
💡 核心价值 :
理解并善用不同策略,是区分普通使用者和高级架构师的关键一步!
二、基石:upstream 模块与 server 参数
在深入策略之前,先回顾 upstream 的基本构成。
upstream backend {
server 192.168.1.10:8080 [parameters];
server 192.168.1.11:8080 [parameters];
}
server 指令常用参数
| 参数 | 作用 |
|---|---|
weight=number |
服务器权重,默认为1。权重越高,接收请求越多。 |
max_fails=number |
在 fail_timeout 时间内,允许请求失败的最大次数。默认为1。 |
fail_timeout=time |
服务器被判定为不可用后的暂停服务时间。默认为10秒。 |
backup |
标记为备份服务器,仅在其他服务器都宕机时启用。 |
down |
手动标记服务器为永久不可用(用于维护)。 |
三、五大核心负载均衡策略详解
策略一:轮询(Round Robin) - 默认策略
原理:最简单的公平调度。Nginx 按照顺序,将每个新请求依次分配给服务器列表中的下一台服务器。
配置:
upstream myapp {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
server 192.168.1.12:8080;
}
适用场景:所有后端服务器性能相近,且无状态(Stateless)的应用。这是最通用、开销最小的策略。
策略二:加权轮询(Weighted Round Robin)
原理 :轮询的升级版。通过 weight 参数,让性能更强的服务器承担更多流量。
配置:
upstream myapp {
server 192.168.1.10:8080 weight=5; # 高配服务器
server 192.168.1.11:8080 weight=2; # 中配服务器
server 192.168.1.12:8080 weight=1; # 低配或旧服务器
}
效果 :每8个请求中,5个去Server1,2个去Server2,1个去Server3。
适用场景:后端服务器硬件配置不均,或你想逐步灰度上线新版本服务器。
策略三:IP哈希(IP Hash)
原理 :根据客户端的 IP 地址进行哈希计算,确保同一个 IP 的请求始终被转发到同一台后端服务器。
配置:
upstream myapp {
ip_hash; # 启用IP哈希
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}
优点 :天然实现会话保持,无需共享 Session 存储。
缺点:
- 如果客户端都在同一个 NAT 网关后(如公司网络),Nginx 看到的都是同一个公网 IP,会导致所有流量都打到一台服务器上,失去负载均衡意义。
- 当后端服务器数量发生变化时,几乎所有客户端的 IP 映射关系都会改变,导致会话丢失。
适用场景:无法使用 Redis 等集中式 Session 存储,且客户端 IP 分布较广的内部系统。
策略四:最少连接(Least Connections)
原理 :Nginx 会将新请求分配给当前活跃连接数最少的服务器。它假设连接数少的服务器当前负载更低。
配置:
upstream myapp {
least_conn; # 启用最少连接
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}
适用场景:后端请求处理时间差异很大(例如,有些请求是简单的读操作,有些是复杂的报表生成)。此策略能更公平地分配负载。
策略五:通用哈希 / 一致性哈希(Hash / Consistent Hash)
注意 :此策略在开源版 Nginx 中需要
ngx_http_upstream_hash_module模块支持(通常已编译进主流发行版)。
原理:
- 通用哈希 (
hash) :基于指定的键(如$request_uri,$cookie_jsessionid)进行哈希,将相同键的请求固定到同一台服务器。 - 一致性哈希 (
hash ... consistent):在通用哈希基础上,采用一致性哈希算法。当增减节点时,能最大程度地减少已有键的重新映射,对缓存系统尤其友好。
配置:
# 基于请求URI的通用哈希
upstream myapp {
hash $request_uri;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}
# 基于Cookie的一致性哈希(推荐用于缓存)
upstream cache_backend {
hash $cookie_user_id consistent;
server 192.168.1.10:11211; # Memcached
server 192.168.1.11:11211;
}
适用场景:
- 通用哈希:需要基于特定业务键(如用户ID、文件名)做路由。
- 一致性哈希:后端是缓存集群(如 Memcached, Redis),希望在扩容/缩容时,缓存失效的比例最小化。
四、生产级配置最佳实践
一个完整的、可用于生产的负载均衡配置,除了选择策略,还需考虑健康检查和超时。
upstream production_backend {
# 选用加权轮询
server app-server-01:8080 weight=3 max_fails=2 fail_timeout=30s;
server app-server-02:8080 weight=3 max_fails=2 fail_timeout=30s;
server app-server-03:8080 weight=1 max_fails=2 fail_timeout=30s backup;
# 如果是缓存,可选用一致性哈希
# hash $request_uri consistent;
}
server {
listen 80;
server_name api.yourcompany.com;
location / {
proxy_pass http://production_backend;
# 必须传递的请求头
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 超时设置
proxy_connect_timeout 5s;
proxy_send_timeout 10s;
proxy_read_timeout 10s;
}
}
五、如何选择正确的策略?
| 你的需求 | 推荐策略 |
|---|---|
| 通用场景,服务器同质 | 轮询 (Round Robin) |
| 服务器性能不同 | 加权轮询 (Weighted Round Robin) |
| 需要会话保持,且无集中式Session | IP哈希 (IP Hash) 或 通用哈希 (Hash) |
| 请求处理时间差异大 | 最少连接 (Least Connections) |
| 后端是缓存集群,需平滑扩缩容 | 一致性哈希 (Consistent Hash) |
六、结语
感谢您的阅读!如果你有任何疑问或想要分享的经验,请在评论区留言交流!